From patchwork Thu Jul 29 06:48:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: You-Sheng Yang X-Patchwork-Id: 1511086 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Gb1PQ0FHFz9sXh; Thu, 29 Jul 2021 16:50:18 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1m8zrx-00078L-QV; Thu, 29 Jul 2021 06:50:13 +0000 Received: from mail-pj1-f45.google.com ([209.85.216.45]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1m8zqh-0006z5-3X for kernel-team@lists.ubuntu.com; Thu, 29 Jul 2021 06:48:55 +0000 Received: by mail-pj1-f45.google.com with SMTP id m1so8913998pjv.2 for ; Wed, 28 Jul 2021 23:48:54 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=+XqAkhFUV3kNJ/QHGBg+eQhyPjhbakPm9bzO1pR777o=; b=OXptKloeiYFWn9tmoalj1bvwaTIkHmWSytzWEJ8Kf8gJEUG7+9VlEprT71XCUVFASY g9rNIYOoG13yqGt9V4J2JzW0+l2OvaHN7VmrQlMobqg/2duyEGn1KSdbPYvf6GGPf52a 37OG2a9uxatWoLIfyu1XZdlp5a3wmd0/RWYrXAlBS526VIld+eGcxtVn5mcUe3zASf1N HwK5AZV8BnmsHsq+YAAGnKmVUUYQRvBllSFpO/gAdZhc1yLzhBWSnXa/8olcIh5d2zG0 KotgdLTn7Qsd+REU7W46ooQy+q8nOUAFPw27xiH/G/JWWt5i0/gm3WpzZDZSa8XjvEl8 gp9g== X-Gm-Message-State: AOAM531Rg2JprTEujO9Se6TnH3kFP1hj1wilBuYJxgumP+QE/8+kh2z9 KnMR4r5d+Xr01RxROYBxRRQYhEHuLe+3wg== X-Google-Smtp-Source: ABdhPJyMGqt/GPQ+Q/WdK1WjyyLjltnJwRYgi5DpZWuLs8NEP0eUXJi8eM1NAN+lt/rifPETscpQAw== X-Received: by 2002:a62:7b83:0:b029:3a9:d407:a383 with SMTP id w125-20020a627b830000b02903a9d407a383mr314589pfc.27.1627541332562; Wed, 28 Jul 2021 23:48:52 -0700 (PDT) Received: from localhost (61-220-137-37.HINET-IP.hinet.net. [61.220.137.37]) by smtp.gmail.com with ESMTPSA id z3sm1886960pjn.43.2021.07.28.23.48.51 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 28 Jul 2021 23:48:52 -0700 (PDT) From: You-Sheng Yang To: kernel-team@lists.ubuntu.com Subject: [PATCH 06/13][SRU][OEM-5.13] UBUNTU: SAUCE: IPU driver release WW14 Date: Thu, 29 Jul 2021 14:48:25 +0800 Message-Id: <20210729064832.25656-7-vicamo.yang@canonical.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210729064832.25656-1-vicamo.yang@canonical.com> References: <20210729064832.25656-1-vicamo.yang@canonical.com> MIME-Version: 1.0 Received-SPF: pass client-ip=209.85.216.45; envelope-from=vicamo@gmail.com; helo=mail-pj1-f45.google.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Wang Yating BugLink: https://bugs.launchpad.net/bugs/1921345 Signed-off-by: Wang Yating (backported from https://github.com/intel/ipu6-drivers/commit/59cd6e387868e95822a438b7c35cc9eb963f0a9a) Signed-off-by: You-Sheng Yang --- drivers/media/i2c/hm11b1.c | 14 +- drivers/media/i2c/ov01a1s.c | 16 +- drivers/media/i2c/pmic_dsc1.c | 158 ------ drivers/media/i2c/power_ctrl_logic.c | 158 ++++++ .../i2c/{pmic_dsc1.h => power_ctrl_logic.h} | 22 +- drivers/media/pci/intel/ipu-cpd.c | 6 +- drivers/media/pci/intel/ipu-fw-isys.c | 2 +- drivers/media/pci/intel/ipu-fw-isys.h | 2 +- drivers/media/pci/intel/ipu-fw-psys.h | 1 + drivers/media/pci/intel/ipu-isys-csi2.c | 2 +- drivers/media/pci/intel/ipu-isys-queue.c | 1 + drivers/media/pci/intel/ipu-isys-video.c | 34 +- drivers/media/pci/intel/ipu-isys-video.h | 2 - drivers/media/pci/intel/ipu-isys.c | 35 +- drivers/media/pci/intel/ipu-isys.h | 6 - drivers/media/pci/intel/ipu-mmu.c | 2 +- drivers/media/pci/intel/ipu-pdata.h | 12 +- drivers/media/pci/intel/ipu-psys.c | 37 +- drivers/media/pci/intel/ipu-psys.h | 6 +- drivers/media/pci/intel/ipu-trace.c | 474 +++++++++--------- drivers/media/pci/intel/ipu-trace.h | 168 +------ drivers/media/pci/intel/ipu.c | 26 +- drivers/media/pci/intel/ipu.h | 2 + drivers/media/pci/intel/ipu6/Makefile | 3 +- .../media/pci/intel/ipu6/ipu-platform-regs.h | 2 +- .../pci/intel/ipu6/ipu-platform-resources.h | 1 + drivers/media/pci/intel/ipu6/ipu-platform.h | 1 + drivers/media/pci/intel/ipu6/ipu-resources.c | 12 + drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c | 14 +- drivers/media/pci/intel/ipu6/ipu6-isys.c | 16 +- .../media/pci/intel/ipu6/ipu6-l-scheduler.c | 40 +- .../pci/intel/ipu6/ipu6-platform-resources.h | 2 +- drivers/media/pci/intel/ipu6/ipu6.c | 8 +- .../pci/intel/ipu6/ipu6ep-fw-resources.c | 393 +++++++++++++++ .../intel/ipu6/ipu6ep-platform-resources.h | 42 ++ 35 files changed, 980 insertions(+), 740 deletions(-) delete mode 100644 drivers/media/i2c/pmic_dsc1.c create mode 100644 drivers/media/i2c/power_ctrl_logic.c rename drivers/media/i2c/{pmic_dsc1.h => power_ctrl_logic.h} (50%) create mode 100644 drivers/media/pci/intel/ipu6/ipu6ep-fw-resources.c create mode 100644 drivers/media/pci/intel/ipu6/ipu6ep-platform-resources.h diff --git a/drivers/media/i2c/hm11b1.c b/drivers/media/i2c/hm11b1.c index 35f49eb7b852..bf6e221150de 100644 --- a/drivers/media/i2c/hm11b1.c +++ b/drivers/media/i2c/hm11b1.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 -// Copyright (c) 2020 Intel Corporation. +// Copyright (c) 2020-2021 Intel Corporation. #include #include @@ -10,7 +10,7 @@ #include #include #include -#include "pmic_dsc1.h" +#include "power_ctrl_logic.h" #define HM11B1_LINK_FREQ_384MHZ 384000000ULL #define HM11B1_SCLK 72000000LL @@ -1001,7 +1001,7 @@ static int hm11b1_start_streaming(struct hm11b1 *hm11b1) int link_freq_index; int ret = 0; - pmic_dsc1_set_power(1); + power_ctrl_logic_set_power(1); link_freq_index = hm11b1->cur_mode->link_freq_index; reg_list = &link_freq_configs[link_freq_index].reg_list; ret = hm11b1_write_reg_list(hm11b1, reg_list); @@ -1036,7 +1036,7 @@ static void hm11b1_stop_streaming(struct hm11b1 *hm11b1) if (hm11b1_write_reg(hm11b1, HM11B1_REG_MODE_SELECT, 1, HM11B1_MODE_STANDBY)) dev_err(&client->dev, "failed to stop streaming"); - pmic_dsc1_set_power(0); + power_ctrl_logic_set_power(0); } static int hm11b1_set_stream(struct v4l2_subdev *sd, int enable) @@ -1278,8 +1278,8 @@ static int hm11b1_probe(struct i2c_client *client) return -ENOMEM; v4l2_i2c_subdev_init(&hm11b1->sd, client, &hm11b1_subdev_ops); - pmic_dsc1_set_power(0); - pmic_dsc1_set_power(1); + power_ctrl_logic_set_power(0); + power_ctrl_logic_set_power(1); ret = hm11b1_identify_module(hm11b1); if (ret) { dev_err(&client->dev, "failed to find sensor: %d", ret); @@ -1320,7 +1320,7 @@ static int hm11b1_probe(struct i2c_client *client) pm_runtime_enable(&client->dev); pm_runtime_idle(&client->dev); - pmic_dsc1_set_power(0); + power_ctrl_logic_set_power(0); return 0; probe_error_media_entity_cleanup: diff --git a/drivers/media/i2c/ov01a1s.c b/drivers/media/i2c/ov01a1s.c index 766fe30116c3..8c66c46be6bc 100644 --- a/drivers/media/i2c/ov01a1s.c +++ b/drivers/media/i2c/ov01a1s.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 -// Copyright (c) 2020 Intel Corporation. +// Copyright (c) 2020-2021 Intel Corporation. #include #include @@ -10,7 +10,7 @@ #include #include #include -#include "pmic_dsc1.h" +#include "power_ctrl_logic.h" #define OV01A1S_LINK_FREQ_400MHZ 400000000ULL #define OV01A1S_SCLK 40000000LL @@ -246,7 +246,7 @@ static const struct ov01a1s_reg sensor_1296x800_setting[] = { {0x3811, 0x00}, {0x3812, 0x00}, {0x3813, 0x09}, - {0x3820, 0x88}, + {0x3820, 0x80}, {0x373d, 0x24}, }; @@ -567,7 +567,7 @@ static int ov01a1s_start_streaming(struct ov01a1s *ov01a1s) int link_freq_index; int ret = 0; - pmic_dsc1_set_power(1); + power_ctrl_logic_set_power(1); link_freq_index = ov01a1s->cur_mode->link_freq_index; reg_list = &link_freq_configs[link_freq_index].reg_list; ret = ov01a1s_write_reg_list(ov01a1s, reg_list); @@ -604,7 +604,7 @@ static void ov01a1s_stop_streaming(struct ov01a1s *ov01a1s) OV01A1S_MODE_STANDBY); if (ret) dev_err(&client->dev, "failed to stop streaming"); - pmic_dsc1_set_power(0); + power_ctrl_logic_set_power(0); } static int ov01a1s_set_stream(struct v4l2_subdev *sd, int enable) @@ -846,8 +846,8 @@ static int ov01a1s_probe(struct i2c_client *client) return -ENOMEM; v4l2_i2c_subdev_init(&ov01a1s->sd, client, &ov01a1s_subdev_ops); - pmic_dsc1_set_power(0); - pmic_dsc1_set_power(1); + power_ctrl_logic_set_power(0); + power_ctrl_logic_set_power(1); ret = ov01a1s_identify_module(ov01a1s); if (ret) { dev_err(&client->dev, "failed to find sensor: %d", ret); @@ -888,7 +888,7 @@ static int ov01a1s_probe(struct i2c_client *client) pm_runtime_enable(&client->dev); pm_runtime_idle(&client->dev); - pmic_dsc1_set_power(0); + power_ctrl_logic_set_power(0); return 0; probe_error_media_entity_cleanup: diff --git a/drivers/media/i2c/pmic_dsc1.c b/drivers/media/i2c/pmic_dsc1.c deleted file mode 100644 index 9892bc506e0b..000000000000 --- a/drivers/media/i2c/pmic_dsc1.c +++ /dev/null @@ -1,158 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (c) 2020 Intel Corporation. - -#include -#include -#include "pmic_dsc1.h" - -/* mcu gpio resources*/ -static const struct acpi_gpio_params camreset_gpio = { 0, 0, false }; -static const struct acpi_gpio_params campwdn_gpio = { 1, 0, false }; -static const struct acpi_gpio_params midmclken_gpio = { 2, 0, false }; -static const struct acpi_gpio_params led_gpio = { 3, 0, false }; -static const struct acpi_gpio_mapping dsc1_acpi_gpios[] = { - { "camreset-gpios", &camreset_gpio, 1 }, - { "campwdn-gpios", &campwdn_gpio, 1 }, - { "midmclken-gpios", &midmclken_gpio, 1 }, - { "indled-gpios", &led_gpio, 1 }, - { } -}; - -static const char * const pin_names[] = { - "camreset", "campwdn", "midmclken", "indled" -}; - -struct pmic_dsc1 pmic = { - .reset_gpio = NULL, - .powerdn_gpio = NULL, - .clocken_gpio = NULL, - .indled_gpio = NULL, - .power_on = false, - .gpio_ready = false, -}; - -static int get_gpio_pin(struct gpio_desc **pin_d, struct pci_dev *pdev, int idx) -{ - int count = PMIC_DSC1_PROBE_MAX_TRY; - - do { - dev_dbg(&pdev->dev, "get %s:tried once\n", pin_names[idx]); - *pin_d = devm_gpiod_get(&pdev->dev, pin_names[idx], - GPIOD_OUT_LOW); - if (!IS_ERR(*pin_d)) - return 0; - *pin_d = NULL; - msleep_interruptible(PMIC_DSC1_PROBE_TRY_GAP); - } while (--count > 0); - - return -EBUSY; -} - -static int pmic_dsc1_probe(struct pci_dev *pdev, - const struct pci_device_id *id) -{ - int ret; - - if (!pdev) { - dev_err(&pdev->dev, "@%s: probed null pdev %x:%x\n", - __func__, PCI_BRG_VENDOR_ID, PCI_BRG_PRODUCT_ID); - return -ENODEV; - } - dev_dbg(&pdev->dev, "@%s, enter\n", __func__); - - ret = devm_acpi_dev_add_driver_gpios(&pdev->dev, dsc1_acpi_gpios); - if (ret) { - dev_err(&pdev->dev, "@%s: fail to add gpio\n", __func__); - return -EBUSY; - } - ret = get_gpio_pin(&pmic.reset_gpio, pdev, 0); - if (ret) - goto pmic_dsc1_probe_end; - ret = get_gpio_pin(&pmic.powerdn_gpio, pdev, 1); - if (ret) - goto pmic_dsc1_probe_end; - ret = get_gpio_pin(&pmic.clocken_gpio, pdev, 2); - if (ret) - goto pmic_dsc1_probe_end; - ret = get_gpio_pin(&pmic.indled_gpio, pdev, 3); - if (ret) - goto pmic_dsc1_probe_end; - - mutex_lock(&pmic.status_lock); - pmic.gpio_ready = true; - mutex_unlock(&pmic.status_lock); - -pmic_dsc1_probe_end: - dev_dbg(&pdev->dev, "@%s, exit\n", __func__); - return ret; -} - -static void pmic_dsc1_remove(struct pci_dev *pdev) -{ - dev_dbg(&pdev->dev, "@%s, enter\n", __func__); - mutex_lock(&pmic.status_lock); - pmic.gpio_ready = false; - gpiod_set_value_cansleep(pmic.reset_gpio, 0); - gpiod_put(pmic.reset_gpio); - gpiod_set_value_cansleep(pmic.powerdn_gpio, 0); - gpiod_put(pmic.powerdn_gpio); - gpiod_set_value_cansleep(pmic.clocken_gpio, 0); - gpiod_put(pmic.clocken_gpio); - gpiod_set_value_cansleep(pmic.indled_gpio, 0); - gpiod_put(pmic.indled_gpio); - mutex_unlock(&pmic.status_lock); - dev_dbg(&pdev->dev, "@%s, exit\n", __func__); -} - -static struct pci_device_id pmic_dsc1_ids[] = { - { PCI_DEVICE(PCI_BRG_VENDOR_ID, PCI_BRG_PRODUCT_ID) }, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, pmic_dsc1_ids); - -static struct pci_driver pmic_dsc1_driver = { - .name = PMIC_DRV_NAME, - .id_table = pmic_dsc1_ids, - .probe = pmic_dsc1_probe, - .remove = pmic_dsc1_remove, -}; - -static int __init pmic_dsc1_init(void) -{ - mutex_init(&pmic.status_lock); - return pci_register_driver(&pmic_dsc1_driver); -} - -static void __exit pmic_dsc1_exit(void) -{ - pci_unregister_driver(&pmic_dsc1_driver); -} -module_init(pmic_dsc1_init); -module_exit(pmic_dsc1_exit); - -int pmic_dsc1_set_power(int on) -{ - mutex_lock(&pmic.status_lock); - if (!pmic.gpio_ready || on < 0 || on > 1) { - pr_debug("@%s,failed to set power, gpio_ready=%d, on=%d\n", - __func__, pmic.gpio_ready, on); - mutex_unlock(&pmic.status_lock); - return -EBUSY; - } - if (pmic.power_on != on) { - gpiod_set_value_cansleep(pmic.reset_gpio, on); - gpiod_set_value_cansleep(pmic.powerdn_gpio, on); - gpiod_set_value_cansleep(pmic.clocken_gpio, on); - gpiod_set_value_cansleep(pmic.indled_gpio, on); - pmic.power_on = on; - } - mutex_unlock(&pmic.status_lock); - return 0; -} -EXPORT_SYMBOL_GPL(pmic_dsc1_set_power); - -MODULE_AUTHOR("Bingbu Cao "); -MODULE_AUTHOR("Qiu, Tianshu "); -MODULE_AUTHOR("Xu, Chongyang "); -MODULE_DESCRIPTION("PMIC-CRDG DSC1 driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/i2c/power_ctrl_logic.c b/drivers/media/i2c/power_ctrl_logic.c new file mode 100644 index 000000000000..17665056eac4 --- /dev/null +++ b/drivers/media/i2c/power_ctrl_logic.c @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2020-2021 Intel Corporation. + +#include +#include +#include "power_ctrl_logic.h" + +/* mcu gpio resources*/ +static const struct acpi_gpio_params camreset_gpio = { 0, 0, false }; +static const struct acpi_gpio_params campwdn_gpio = { 1, 0, false }; +static const struct acpi_gpio_params midmclken_gpio = { 2, 0, false }; +static const struct acpi_gpio_params led_gpio = { 3, 0, false }; +static const struct acpi_gpio_mapping dsc1_acpi_gpios[] = { + { "camreset-gpios", &camreset_gpio, 1 }, + { "campwdn-gpios", &campwdn_gpio, 1 }, + { "midmclken-gpios", &midmclken_gpio, 1 }, + { "indled-gpios", &led_gpio, 1 }, + { } +}; + +static const char * const pin_names[] = { + "camreset", "campwdn", "midmclken", "indled" +}; + +static struct power_ctrl_logic pcl = { + .reset_gpio = NULL, + .powerdn_gpio = NULL, + .clocken_gpio = NULL, + .indled_gpio = NULL, + .power_on = false, + .gpio_ready = false, +}; + +static int get_gpio_pin(struct gpio_desc **pin_d, struct pci_dev *pdev, int idx) +{ + int count = PCL_PROBE_MAX_TRY; + + do { + dev_dbg(&pdev->dev, "get %s:tried once\n", pin_names[idx]); + *pin_d = devm_gpiod_get(&pdev->dev, pin_names[idx], + GPIOD_OUT_LOW); + if (!IS_ERR(*pin_d)) + return 0; + *pin_d = NULL; + msleep_interruptible(PCL_PROBE_TRY_GAP); + } while (--count > 0); + + return -EBUSY; +} + +static int power_ctrl_logic_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + int ret; + + if (!pdev) { + dev_err(&pdev->dev, "@%s: probed null pdev %x:%x\n", + __func__, PCL_PCI_BRG_VEN_ID, PCL_PCI_BRG_PDT_ID); + return -ENODEV; + } + dev_dbg(&pdev->dev, "@%s, enter\n", __func__); + + ret = devm_acpi_dev_add_driver_gpios(&pdev->dev, dsc1_acpi_gpios); + if (ret) { + dev_err(&pdev->dev, "@%s: fail to add gpio\n", __func__); + return -EBUSY; + } + ret = get_gpio_pin(&pcl.reset_gpio, pdev, 0); + if (ret) + goto power_ctrl_logic_probe_end; + ret = get_gpio_pin(&pcl.powerdn_gpio, pdev, 1); + if (ret) + goto power_ctrl_logic_probe_end; + ret = get_gpio_pin(&pcl.clocken_gpio, pdev, 2); + if (ret) + goto power_ctrl_logic_probe_end; + ret = get_gpio_pin(&pcl.indled_gpio, pdev, 3); + if (ret) + goto power_ctrl_logic_probe_end; + + mutex_lock(&pcl.status_lock); + pcl.gpio_ready = true; + mutex_unlock(&pcl.status_lock); + +power_ctrl_logic_probe_end: + dev_dbg(&pdev->dev, "@%s, exit\n", __func__); + return ret; +} + +static void power_ctrl_logic_remove(struct pci_dev *pdev) +{ + dev_dbg(&pdev->dev, "@%s, enter\n", __func__); + mutex_lock(&pcl.status_lock); + pcl.gpio_ready = false; + gpiod_set_value_cansleep(pcl.reset_gpio, 0); + gpiod_put(pcl.reset_gpio); + gpiod_set_value_cansleep(pcl.powerdn_gpio, 0); + gpiod_put(pcl.powerdn_gpio); + gpiod_set_value_cansleep(pcl.clocken_gpio, 0); + gpiod_put(pcl.clocken_gpio); + gpiod_set_value_cansleep(pcl.indled_gpio, 0); + gpiod_put(pcl.indled_gpio); + mutex_unlock(&pcl.status_lock); + dev_dbg(&pdev->dev, "@%s, exit\n", __func__); +} + +static struct pci_device_id power_ctrl_logic_ids[] = { + { PCI_DEVICE(PCL_PCI_BRG_VEN_ID, PCL_PCI_BRG_PDT_ID) }, + { 0, }, +}; +MODULE_DEVICE_TABLE(pci, power_ctrl_logic_ids); + +static struct pci_driver power_ctrl_logic_driver = { + .name = PCL_DRV_NAME, + .id_table = power_ctrl_logic_ids, + .probe = power_ctrl_logic_probe, + .remove = power_ctrl_logic_remove, +}; + +static int __init power_ctrl_logic_init(void) +{ + mutex_init(&pcl.status_lock); + return pci_register_driver(&power_ctrl_logic_driver); +} + +static void __exit power_ctrl_logic_exit(void) +{ + pci_unregister_driver(&power_ctrl_logic_driver); +} +module_init(power_ctrl_logic_init); +module_exit(power_ctrl_logic_exit); + +int power_ctrl_logic_set_power(int on) +{ + mutex_lock(&pcl.status_lock); + if (!pcl.gpio_ready || on < 0 || on > 1) { + pr_debug("@%s,failed to set power, gpio_ready=%d, on=%d\n", + __func__, pcl.gpio_ready, on); + mutex_unlock(&pcl.status_lock); + return -EBUSY; + } + if (pcl.power_on != on) { + gpiod_set_value_cansleep(pcl.reset_gpio, on); + gpiod_set_value_cansleep(pcl.powerdn_gpio, on); + gpiod_set_value_cansleep(pcl.clocken_gpio, on); + gpiod_set_value_cansleep(pcl.indled_gpio, on); + pcl.power_on = on; + } + mutex_unlock(&pcl.status_lock); + return 0; +} +EXPORT_SYMBOL_GPL(power_ctrl_logic_set_power); + +MODULE_AUTHOR("Bingbu Cao "); +MODULE_AUTHOR("Qiu, Tianshu "); +MODULE_AUTHOR("Xu, Chongyang "); +MODULE_DESCRIPTION("Power Control Logic Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/i2c/pmic_dsc1.h b/drivers/media/i2c/power_ctrl_logic.h similarity index 50% rename from drivers/media/i2c/pmic_dsc1.h rename to drivers/media/i2c/power_ctrl_logic.h index 19f1112f85f8..1c6d71dcc62f 100644 --- a/drivers/media/i2c/pmic_dsc1.h +++ b/drivers/media/i2c/power_ctrl_logic.h @@ -1,22 +1,22 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (c) 2020 Intel Corporation. */ +/* Copyright (c) 2020-2021 Intel Corporation. */ -#ifndef _PMIC_DSC1_H_ -#define _PMIC_DSC1_H_ +#ifndef _POWER_CTRL_LOGIC_H_ +#define _POWER_CTRL_LOGIC_H_ #include #include #include -/* pmic dsc1 pci id */ -#define PCI_BRG_VENDOR_ID 0x8086 -#define PCI_BRG_PRODUCT_ID 0x9a14 +/* pci id for probe power control logic*/ +#define PCL_PCI_BRG_VEN_ID 0x8086 +#define PCL_PCI_BRG_PDT_ID 0x9a14 -#define PMIC_DRV_NAME "pmic_dsc1" -#define PMIC_DSC1_PROBE_MAX_TRY 5 -#define PMIC_DSC1_PROBE_TRY_GAP 500 /* in millseconds */ +#define PCL_DRV_NAME "power_ctrl_logic" +#define PCL_PROBE_MAX_TRY 5 +#define PCL_PROBE_TRY_GAP 500 /* in millseconds */ -struct pmic_dsc1 { +struct power_ctrl_logic { /* gpio resource*/ struct gpio_desc *reset_gpio; struct gpio_desc *powerdn_gpio; @@ -29,5 +29,5 @@ struct pmic_dsc1 { }; /* exported function for extern module */ -int pmic_dsc1_set_power(int on); +int power_ctrl_logic_set_power(int on); #endif diff --git a/drivers/media/pci/intel/ipu-cpd.c b/drivers/media/pci/intel/ipu-cpd.c index cfd5f4013608..3833f3f0bd8d 100644 --- a/drivers/media/pci/intel/ipu-cpd.c +++ b/drivers/media/pci/intel/ipu-cpd.c @@ -180,7 +180,7 @@ static int ipu_cpd_parse_module_data(struct ipu_device *isp, *p++ = dma_addr_module_data + dir_ent->offset; - if (ipu_ver == IPU_VER_6) + if (ipu_ver == IPU_VER_6 || ipu_ver == IPU_VER_6EP) id = ipu6_cpd_metadata_get_cmpnt_id(isp, metadata, metadata_size, i); else @@ -193,7 +193,7 @@ static int ipu_cpd_parse_module_data(struct ipu_device *isp, return -EINVAL; } - if (ipu_ver == IPU_VER_6) + if (ipu_ver == IPU_VER_6 || ipu_ver == IPU_VER_6EP) ver = ipu6_cpd_metadata_cmpnt_version(isp, metadata, metadata_size, i); else @@ -377,7 +377,7 @@ static int ipu_cpd_validate_metadata(struct ipu_device *isp, } /* Validate metadata size multiple of metadata components */ - if (ipu_ver == IPU_VER_6) + if (ipu_ver == IPU_VER_6 || ipu_ver == IPU_VER_6EP) size = sizeof(struct ipu6_cpd_metadata_cmpnt); else size = sizeof(struct ipu_cpd_metadata_cmpnt); diff --git a/drivers/media/pci/intel/ipu-fw-isys.c b/drivers/media/pci/intel/ipu-fw-isys.c index 307117818a52..ee064faaa013 100644 --- a/drivers/media/pci/intel/ipu-fw-isys.c +++ b/drivers/media/pci/intel/ipu-fw-isys.c @@ -523,7 +523,7 @@ int ipu_fw_isys_init(struct ipu_isys *isys, unsigned int num_streams) if (ipu_ver == IPU_VER_6SE) { ipu6se_isys_fwcom_cfg_init(isys, &fwcom, num_streams); - } else if (ipu_ver == IPU_VER_6) { + } else if (ipu_ver == IPU_VER_6 || ipu_ver == IPU_VER_6EP) { ipu6_isys_fwcom_cfg_init(isys, &fwcom, num_streams); } else { dev_err(dev, "unsupported ipu_ver %d\n", ipu_ver); diff --git a/drivers/media/pci/intel/ipu-fw-isys.h b/drivers/media/pci/intel/ipu-fw-isys.h index 4d1140c0dc32..ec4c4c310fec 100644 --- a/drivers/media/pci/intel/ipu-fw-isys.h +++ b/drivers/media/pci/intel/ipu-fw-isys.h @@ -584,7 +584,7 @@ struct ipu_fw_isys_param_pin_abi { * @input_res: input resolution * @dt: mipi data type ((enum ipu_fw_isys_mipi_data_type) * @mipi_store_mode: defines if legacy long packet header will be stored or - * discarded if discarded, output pin pin type for this + * discarded if discarded, output pin type for this * input pin can only be MIPI * (enum ipu_fw_isys_mipi_store_mode) * @bits_per_pix: native bits per pixel diff --git a/drivers/media/pci/intel/ipu-fw-psys.h b/drivers/media/pci/intel/ipu-fw-psys.h index f8f356104c05..f1dcc9dd946c 100644 --- a/drivers/media/pci/intel/ipu-fw-psys.h +++ b/drivers/media/pci/intel/ipu-fw-psys.h @@ -6,6 +6,7 @@ #include "ipu6-platform-resources.h" #include "ipu6se-platform-resources.h" +#include "ipu6ep-platform-resources.h" #define IPU_FW_PSYS_CMD_QUEUE_SIZE 0x20 #define IPU_FW_PSYS_EVENT_QUEUE_SIZE 0x40 diff --git a/drivers/media/pci/intel/ipu-isys-csi2.c b/drivers/media/pci/intel/ipu-isys-csi2.c index bf0aba76c6ae..4437e1bf88b2 100644 --- a/drivers/media/pci/intel/ipu-isys-csi2.c +++ b/drivers/media/pci/intel/ipu-isys-csi2.c @@ -149,7 +149,7 @@ static const struct v4l2_subdev_core_ops csi2_sd_core_ops = { * where * UI = 1 / (2 * F) in seconds * COUNT_ACC = counter accuracy in seconds - * For IPU4, COUNT_ACC = 0.125 ns + * For legacy IPU, COUNT_ACC = 0.125 ns * * A and B are coefficients from the table below, * depending whether the register minimum or maximum value is diff --git a/drivers/media/pci/intel/ipu-isys-queue.c b/drivers/media/pci/intel/ipu-isys-queue.c index 1f379f0464a1..ce217e84cc53 100644 --- a/drivers/media/pci/intel/ipu-isys-queue.c +++ b/drivers/media/pci/intel/ipu-isys-queue.c @@ -840,6 +840,7 @@ get_sof_sequence_by_timestamp(struct ipu_isys_pipeline *ip, */ if (time == 0) return atomic_read(&ip->sequence) - 1; + for (i = 0; i < IPU_ISYS_MAX_PARALLEL_SOF; i++) if (time == ip->seq[i].timestamp) { dev_dbg(&isys->adev->dev, diff --git a/drivers/media/pci/intel/ipu-isys-video.c b/drivers/media/pci/intel/ipu-isys-video.c index d1c76ee4c3de..f4fc3c92d45d 100644 --- a/drivers/media/pci/intel/ipu-isys-video.c +++ b/drivers/media/pci/intel/ipu-isys-video.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2013 - 2020 Intel Corporation +// Copyright (C) 2013 - 2021 Intel Corporation #include #include @@ -545,9 +545,7 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input) static bool is_external(struct ipu_isys_video *av, struct media_entity *entity) { struct v4l2_subdev *sd; -#ifdef CONFIG_VIDEO_INTEL_IPU_TPG unsigned int i; -#endif /* All video nodes are ours. */ if (!is_media_entity_v4l2_subdev(entity)) @@ -558,12 +556,10 @@ static bool is_external(struct ipu_isys_video *av, struct media_entity *entity) strlen(IPU_ISYS_ENTITY_PREFIX)) != 0) return true; -#ifdef CONFIG_VIDEO_INTEL_IPU_TPG for (i = 0; i < av->isys->pdata->ipdata->tpg.ntpgs && av->isys->tpg[i].isys; i++) if (entity == &av->isys->tpg[i].asd.sd.entity) return true; -#endif return false; } @@ -680,11 +676,10 @@ static void short_packet_queue_destroy(struct ipu_isys_pipeline *ip) return; for (i = 0; i < IPU_ISYS_SHORT_PACKET_BUFFER_NUM; i++) { if (ip->short_packet_bufs[i].buffer) - dma_free_noncoherent(&av->isys->adev->dev, - ip->short_packet_buffer_size, - ip->short_packet_bufs[i].buffer, - ip->short_packet_bufs[i].dma_addr, - DMA_BIDIRECTIONAL); + dma_free_coherent(&av->isys->adev->dev, + ip->short_packet_buffer_size, + ip->short_packet_bufs[i].buffer, + ip->short_packet_bufs[i].dma_addr); } kfree(ip->short_packet_bufs); ip->short_packet_bufs = NULL; @@ -731,11 +726,10 @@ static int short_packet_queue_setup(struct ipu_isys_pipeline *ip) buf->ip = ip; buf->ib.type = IPU_ISYS_SHORT_PACKET_BUFFER; buf->bytesused = buf_size; - buf->buffer = dma_alloc_noncoherent(&av->isys->adev->dev, - buf_size, - &buf->dma_addr, - DMA_BIDIRECTIONAL, - GFP_KERNEL); + buf->buffer = dma_alloc_coherent(&av->isys->adev->dev, + buf_size, + &buf->dma_addr, + GFP_KERNEL); if (!buf->buffer) { short_packet_queue_destroy(ip); return -ENOMEM; @@ -988,11 +982,9 @@ static int start_stream_firmware(struct ipu_isys_video *av, if (ip->csi2 && !v4l2_ctrl_g_ctrl(ip->csi2->store_csi2_header)) stream_cfg->input_pins[0].mipi_store_mode = IPU_FW_ISYS_MIPI_STORE_MODE_DISCARD_LONG_HEADER; -#ifdef CONFIG_VIDEO_INTEL_IPU_TPG else if (ip->tpg && !v4l2_ctrl_g_ctrl(ip->tpg->store_csi2_header)) stream_cfg->input_pins[0].mipi_store_mode = IPU_FW_ISYS_MIPI_STORE_MODE_DISCARD_LONG_HEADER; -#endif stream_cfg->src = ip->source; stream_cfg->vc = 0; @@ -1306,9 +1298,7 @@ int ipu_isys_video_prepare_streaming(struct ipu_isys_video *av, ip->csi2_be = NULL; ip->csi2_be_soc = NULL; ip->csi2 = NULL; -#ifdef CONFIG_VIDEO_INTEL_IPU_TPG ip->tpg = NULL; -#endif ip->seq_index = 0; memset(ip->seq, 0, sizeof(ip->seq)); @@ -1426,9 +1416,11 @@ static void calculate_stream_datarate(struct video_stream_watermark *watermark) { u64 pixels_per_line, bytes_per_line, line_time_ns; u64 pages_per_line, pb_bytes_per_line, stream_data_rate; - u16 sram_granulrity_shift = (ipu_ver == IPU_VER_6) ? + u16 sram_granulrity_shift = + (ipu_ver == IPU_VER_6 || ipu_ver == IPU_VER_6EP) ? IPU6_SRAM_GRANULRITY_SHIFT : IPU6SE_SRAM_GRANULRITY_SHIFT; - u16 sram_granulrity_size = (ipu_ver == IPU_VER_6) ? + u16 sram_granulrity_size = + (ipu_ver == IPU_VER_6 || ipu_ver == IPU_VER_6EP) ? IPU6_SRAM_GRANULRITY_SIZE : IPU6SE_SRAM_GRANULRITY_SIZE; pixels_per_line = watermark->width + watermark->hblank; diff --git a/drivers/media/pci/intel/ipu-isys-video.h b/drivers/media/pci/intel/ipu-isys-video.h index 6d8701d28843..e59218257b1d 100644 --- a/drivers/media/pci/intel/ipu-isys-video.h +++ b/drivers/media/pci/intel/ipu-isys-video.h @@ -54,9 +54,7 @@ struct ipu_isys_pipeline { struct ipu_isys_csi2_be *csi2_be; struct ipu_isys_csi2_be_soc *csi2_be_soc; struct ipu_isys_csi2 *csi2; -#ifdef CONFIG_VIDEO_INTEL_IPU_TPG struct ipu_isys_tpg *tpg; -#endif /* * Number of capture queues, write access serialised using struct diff --git a/drivers/media/pci/intel/ipu-isys.c b/drivers/media/pci/intel/ipu-isys.c index a193d7ed041c..4e616343c5f3 100644 --- a/drivers/media/pci/intel/ipu-isys.c +++ b/drivers/media/pci/intel/ipu-isys.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2013 - 2020 Intel Corporation +// Copyright (C) 2013 - 2021 Intel Corporation #include #include @@ -29,9 +29,7 @@ #include "ipu-dma.h" #include "ipu-isys.h" #include "ipu-isys-csi2.h" -#ifdef CONFIG_VIDEO_INTEL_IPU_TPG #include "ipu-isys-tpg.h" -#endif #include "ipu-isys-video.h" #include "ipu-platform-regs.h" #include "ipu-buttress.h" @@ -133,10 +131,8 @@ isys_complete_ext_device_registration(struct ipu_isys *isys, static void isys_unregister_subdevices(struct ipu_isys *isys) { -#ifdef CONFIG_VIDEO_INTEL_IPU_TPG const struct ipu_isys_internal_tpg_pdata *tpg = &isys->pdata->ipdata->tpg; -#endif const struct ipu_isys_internal_csi2_pdata *csi2 = &isys->pdata->ipdata->csi2; unsigned int i; @@ -145,10 +141,8 @@ static void isys_unregister_subdevices(struct ipu_isys *isys) for (i = 0; i < NR_OF_CSI2_BE_SOC_DEV; i++) ipu_isys_csi2_be_soc_cleanup(&isys->csi2_be_soc[i]); -#ifdef CONFIG_VIDEO_INTEL_IPU_TPG for (i = 0; i < tpg->ntpgs; i++) ipu_isys_tpg_cleanup(&isys->tpg[i]); -#endif for (i = 0; i < csi2->nports; i++) ipu_isys_csi2_cleanup(&isys->csi2[i]); @@ -156,10 +150,8 @@ static void isys_unregister_subdevices(struct ipu_isys *isys) static int isys_register_subdevices(struct ipu_isys *isys) { -#ifdef CONFIG_VIDEO_INTEL_IPU_TPG const struct ipu_isys_internal_tpg_pdata *tpg = &isys->pdata->ipdata->tpg; -#endif const struct ipu_isys_internal_csi2_pdata *csi2 = &isys->pdata->ipdata->csi2; struct ipu_isys_csi2_be_soc *csi2_be_soc; @@ -183,7 +175,6 @@ static int isys_register_subdevices(struct ipu_isys *isys) isys->isr_csi2_bits |= IPU_ISYS_UNISPART_IRQ_CSI2(i); } -#ifdef CONFIG_VIDEO_INTEL_IPU_TPG isys->tpg = devm_kcalloc(&isys->adev->dev, tpg->ntpgs, sizeof(*isys->tpg), GFP_KERNEL); if (!isys->tpg) { @@ -200,7 +191,6 @@ static int isys_register_subdevices(struct ipu_isys *isys) if (rval) goto fail; } -#endif for (k = 0; k < NR_OF_CSI2_BE_SOC_DEV; k++) { rval = ipu_isys_csi2_be_soc_init(&isys->csi2_be_soc[k], @@ -244,7 +234,6 @@ static int isys_register_subdevices(struct ipu_isys *isys) } } -#ifdef CONFIG_VIDEO_INTEL_IPU_TPG for (i = 0; i < tpg->ntpgs; i++) { rval = media_create_pad_link(&isys->tpg[i].asd.sd.entity, TPG_PAD_SOURCE, @@ -270,7 +259,6 @@ static int isys_register_subdevices(struct ipu_isys *isys) } } } -#endif return 0; @@ -398,9 +386,11 @@ void update_watermark_setting(struct ipu_isys *isys) u32 iwake_threshold, iwake_critical_threshold; u64 threshold_bytes; u64 isys_pb_datarate_mbs = 0; - u16 sram_granulrity_shift = (ipu_ver == IPU_VER_6) ? + u16 sram_granulrity_shift = + (ipu_ver == IPU_VER_6 || ipu_ver == IPU_VER_6EP) ? IPU6_SRAM_GRANULRITY_SHIFT : IPU6SE_SRAM_GRANULRITY_SHIFT; - int max_sram_size = (ipu_ver == IPU_VER_6) ? + int max_sram_size = + (ipu_ver == IPU_VER_6 || ipu_ver == IPU_VER_6EP) ? IPU6_MAX_SRAM_SIZE : IPU6SE_MAX_SRAM_SIZE; mutex_lock(&iwake_watermark->mutex); @@ -827,10 +817,10 @@ static void isys_remove(struct ipu_bus_device *adev) if (isys->short_packet_source == IPU_ISYS_SHORT_PACKET_FROM_TUNIT) { u32 trace_size = IPU_ISYS_SHORT_PACKET_TRACE_BUFFER_SIZE; - dma_free_noncoherent(&adev->dev, trace_size, - isys->short_packet_trace_buffer, - isys->short_packet_trace_buffer_dma_addr, - DMA_BIDIRECTIONAL); + + dma_free_coherent(&adev->dev, trace_size, + isys->short_packet_trace_buffer, + isys->short_packet_trace_buffer_dma_addr); } } @@ -1047,7 +1037,7 @@ static int isys_probe(struct ipu_bus_device *adev) isys->pdata = adev->pdata; /* initial streamID for different sensor types */ - if (ipu_ver == IPU_VER_6) { + if (ipu_ver == IPU_VER_6 || ipu_ver == IPU_VER_6EP) { isys->sensor_info.vc1_data_start = IPU6_FW_ISYS_VC1_SENSOR_DATA_START; isys->sensor_info.vc1_data_end = @@ -1360,11 +1350,9 @@ int isys_isr_one(struct ipu_bus_device *adev) if (pipe->csi2) ipu_isys_csi2_sof_event(pipe->csi2); -#ifdef CONFIG_VIDEO_INTEL_IPU_TPG #ifdef IPU_TPG_FRAME_SYNC if (pipe->tpg) ipu_isys_tpg_sof_event(pipe->tpg); -#endif #endif pipe->seq[pipe->seq_index].sequence = atomic_read(&pipe->sequence) - 1; @@ -1380,11 +1368,9 @@ int isys_isr_one(struct ipu_bus_device *adev) if (pipe->csi2) ipu_isys_csi2_eof_event(pipe->csi2); -#ifdef CONFIG_VIDEO_INTEL_IPU_TPG #ifdef IPU_TPG_FRAME_SYNC if (pipe->tpg) ipu_isys_tpg_eof_event(pipe->tpg); -#endif #endif dev_dbg(&adev->dev, @@ -1450,6 +1436,7 @@ module_ipu_bus_driver(isys_driver); static const struct pci_device_id ipu_pci_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, IPU6_PCI_ID)}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, IPU6SE_PCI_ID)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, IPU6EP_PCI_ID)}, {0,} }; MODULE_DEVICE_TABLE(pci, ipu_pci_tbl); diff --git a/drivers/media/pci/intel/ipu-isys.h b/drivers/media/pci/intel/ipu-isys.h index 343f0d773b9d..5d82b934b453 100644 --- a/drivers/media/pci/intel/ipu-isys.h +++ b/drivers/media/pci/intel/ipu-isys.h @@ -16,9 +16,7 @@ #include "ipu-isys-media.h" #include "ipu-isys-csi2.h" #include "ipu-isys-csi2-be.h" -#ifdef CONFIG_VIDEO_INTEL_IPU_TPG #include "ipu-isys-tpg.h" -#endif #include "ipu-isys-video.h" #include "ipu-pdata.h" #include "ipu-fw-isys.h" @@ -133,9 +131,7 @@ struct ipu_isys_sensor_info { * @lib_mutex: optional external library mutex * @pdata: platform data pointer * @csi2: CSI-2 receivers -#ifdef CONFIG_VIDEO_INTEL_IPU_TPG * @tpg: test pattern generators -#endif * @csi2_be: CSI-2 back-ends * @fw: ISYS firmware binary (unsecure firmware) * @fw_sgt: fw scatterlist @@ -175,9 +171,7 @@ struct ipu_isys { struct ipu_isys_pdata *pdata; struct ipu_isys_csi2 *csi2; -#ifdef CONFIG_VIDEO_INTEL_IPU_TPG struct ipu_isys_tpg *tpg; -#endif struct ipu_isys_csi2_be csi2_be; struct ipu_isys_csi2_be_soc csi2_be_soc[NR_OF_CSI2_BE_SOC_DEV]; const struct firmware *fw; diff --git a/drivers/media/pci/intel/ipu-mmu.c b/drivers/media/pci/intel/ipu-mmu.c index 476ef7b5cc2e..baa9826f9500 100644 --- a/drivers/media/pci/intel/ipu-mmu.c +++ b/drivers/media/pci/intel/ipu-mmu.c @@ -135,7 +135,7 @@ static void tlb_invalidate(struct ipu_mmu *mmu) for (i = 0; i < mmu->nr_mmus; i++) { /* - * To avoid the HW bug induced dead lock in some of the IPU4 + * To avoid the HW bug induced dead lock in some of the IPU * MMUs on successive invalidate calls, we need to first do a * read to the page table base before writing the invalidate * register. MMUs which need to implement this WA, will have diff --git a/drivers/media/pci/intel/ipu-pdata.h b/drivers/media/pci/intel/ipu-pdata.h index 3dd7205994b4..5498956b8ce7 100644 --- a/drivers/media/pci/intel/ipu-pdata.h +++ b/drivers/media/pci/intel/ipu-pdata.h @@ -35,7 +35,7 @@ * psys has 4 ports with IOSF interface for VC0, VC1w, VC1r and VC2 * * Threshold values are pre-defined and are arrived at after performance - * evaluations on a type of IPU4 + * evaluations on a type of IPU */ #define IPU_MAX_VC_IOSF_PORTS 4 @@ -60,7 +60,7 @@ struct ipu_isys_subdev_pdata; /* * MMU Invalidation HW bug workaround by ZLW mechanism * - * IPU4 MMUV2 has a bug in the invalidation mechanism which might result in + * Old IPU MMUV2 has a bug in the invalidation mechanism which might result in * wrong translation or replication of the translation. This will cause data * corruption. So we cannot directly use the MMU V2 invalidation registers * to invalidate the MMU. Instead, whenever an invalidate is called, we need to @@ -98,7 +98,7 @@ struct ipu_isys_subdev_pdata; #define MMUV2_TRASH_L2_BLOCK_OFFSET IPU_MMUV2_L2_RANGE /* - * In some of the IPU4 MMUs, there is provision to configure L1 and L2 page + * In some of the IPU MMUs, there is provision to configure L1 and L2 page * table caches. Both these L1 and L2 caches are divided into multiple sections * called streams. There is maximum 16 streams for both caches. Each of these * sections are subdivided into multiple blocks. When nr_l1streams = 0 and @@ -154,7 +154,7 @@ struct ipu_isys_subdev_pdata; * * Currently L1/L2 streams, blocks, AT ZLW configurations etc. are pre-defined * as per the usecase specific calculations. Any change to this pre-defined - * table has to happen in sync with IPU4 FW. + * table has to happen in sync with IPU FW. */ struct ipu_mmu_hw { union { @@ -207,13 +207,11 @@ struct ipu_isys_internal_csi2_pdata { unsigned int *offsets; }; -#ifdef CONFIG_VIDEO_INTEL_IPU_TPG struct ipu_isys_internal_tpg_pdata { unsigned int ntpgs; unsigned int *offsets; unsigned int *sels; }; -#endif /* * One place to handle all the IPU HW variations @@ -230,9 +228,7 @@ struct ipu_hw_variants { struct ipu_isys_internal_pdata { struct ipu_isys_internal_csi2_pdata csi2; -#ifdef CONFIG_VIDEO_INTEL_IPU_TPG struct ipu_isys_internal_tpg_pdata tpg; -#endif struct ipu_hw_variants hw_variant; u32 num_parallel_streams; u32 isys_dma_overshoot; diff --git a/drivers/media/pci/intel/ipu-psys.c b/drivers/media/pci/intel/ipu-psys.c index 0efed22ae8b8..37964b2965d9 100644 --- a/drivers/media/pci/intel/ipu-psys.c +++ b/drivers/media/pci/intel/ipu-psys.c @@ -881,20 +881,20 @@ static int psys_runtime_pm_resume(struct device *dev) if (!psys) return 0; - retval = ipu_mmu_hw_init(adev->mmu); - if (retval) - return retval; - /* * In runtime autosuspend mode, if the psys is in power on state, no * need to resume again. */ - spin_lock_irqsave(&psys->power_lock, flags); - if (psys->power) { - spin_unlock_irqrestore(&psys->power_lock, flags); + spin_lock_irqsave(&psys->ready_lock, flags); + if (psys->ready) { + spin_unlock_irqrestore(&psys->ready_lock, flags); return 0; } - spin_unlock_irqrestore(&psys->power_lock, flags); + spin_unlock_irqrestore(&psys->ready_lock, flags); + + retval = ipu_mmu_hw_init(adev->mmu); + if (retval) + return retval; if (async_fw_init && !psys->fwcom) { dev_err(dev, @@ -925,9 +925,9 @@ static int psys_runtime_pm_resume(struct device *dev) return retval; } - spin_lock_irqsave(&psys->power_lock, flags); - psys->power = 1; - spin_unlock_irqrestore(&psys->power_lock, flags); + spin_lock_irqsave(&psys->ready_lock, flags); + psys->ready = 1; + spin_unlock_irqrestore(&psys->ready_lock, flags); return 0; } @@ -942,12 +942,12 @@ static int psys_runtime_pm_suspend(struct device *dev) if (!psys) return 0; - if (!psys->power) + if (!psys->ready) return 0; - spin_lock_irqsave(&psys->power_lock, flags); - psys->power = 0; - spin_unlock_irqrestore(&psys->power_lock, flags); + spin_lock_irqsave(&psys->ready_lock, flags); + psys->ready = 0; + spin_unlock_irqrestore(&psys->ready_lock, flags); /* * We can trace failure but better to not return an error. @@ -1233,7 +1233,7 @@ static int ipu_psys_fw_init(struct ipu_psys *psys) int i; size = IPU6SE_FW_PSYS_N_PSYS_CMD_QUEUE_ID; - if (ipu_ver == IPU_VER_6) + if (ipu_ver == IPU_VER_6 || ipu_ver == IPU_VER_6EP) size = IPU6_FW_PSYS_N_PSYS_CMD_QUEUE_ID; queue_cfg = devm_kzalloc(&psys->adev->dev, sizeof(*queue_cfg) * size, @@ -1321,9 +1321,9 @@ static int ipu_psys_probe(struct ipu_bus_device *adev) set_bit(minor, ipu_psys_devices); - spin_lock_init(&psys->power_lock); + spin_lock_init(&psys->ready_lock); spin_lock_init(&psys->pgs_lock); - psys->power = 0; + psys->ready = 0; psys->timeout = IPU_PSYS_CMD_TIMEOUT_MS; mutex_init(&psys->mutex); @@ -1598,6 +1598,7 @@ static void __exit ipu_psys_exit(void) static const struct pci_device_id ipu_pci_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, IPU6_PCI_ID)}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, IPU6SE_PCI_ID)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, IPU6EP_PCI_ID)}, {0,} }; MODULE_DEVICE_TABLE(pci, ipu_pci_tbl); diff --git a/drivers/media/pci/intel/ipu-psys.h b/drivers/media/pci/intel/ipu-psys.h index 7a1d7d42c98d..b5ddf50791d7 100644 --- a/drivers/media/pci/intel/ipu-psys.h +++ b/drivers/media/pci/intel/ipu-psys.h @@ -65,7 +65,7 @@ struct ipu_psys_resource_pool { /* * This struct keeps book of the resources allocated for a specific PG. * It is used for freeing up resources from struct ipu_psys_resources - * when the PG is released from IPU4 (or model of IPU4). + * when the PG is released from IPU (or model of IPU). */ struct ipu_psys_resource_alloc { u32 cells; /* Bitmask of cells needed */ @@ -81,10 +81,10 @@ struct ipu_psys { struct device dev; struct mutex mutex; /* Psys various */ - int power; + int ready; /* psys fw status */ bool icache_prefetch_sp; bool icache_prefetch_isp; - spinlock_t power_lock; /* Serialize access to power */ + spinlock_t ready_lock; /* protect psys firmware state */ spinlock_t pgs_lock; /* Protect pgs list access */ struct list_head fhs; struct list_head pgs; diff --git a/drivers/media/pci/intel/ipu-trace.c b/drivers/media/pci/intel/ipu-trace.c index b3042993298a..99b209df3d1f 100644 --- a/drivers/media/pci/intel/ipu-trace.c +++ b/drivers/media/pci/intel/ipu-trace.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2014 - 2020 Intel Corporation +// Copyright (C) 2014 - 2021 Intel Corporation #include #include @@ -15,56 +15,11 @@ #include "ipu-platform-regs.h" #include "ipu-trace.h" -/* Input data processing states */ -enum config_file_parse_states { - STATE_FILL = 0, - STATE_COMMENT, - STATE_COMPLETE, -}; - struct trace_register_range { u32 start; u32 end; }; -static u16 trace_unit_template[] = TRACE_REG_CREATE_TUN_REGISTER_LIST; -static u16 trace_monitor_template[] = TRACE_REG_CREATE_TM_REGISTER_LIST; -static u16 trace_gpc_template[] = TRACE_REG_CREATE_GPC_REGISTER_LIST; - -static struct trace_register_range trace_csi2_range_template[] = { - { - .start = TRACE_REG_CSI2_TM_RESET_REG_IDX, - .end = TRACE_REG_CSI2_TM_IRQ_ENABLE_REG_ID_N(7) - }, - { - .start = TRACE_REG_END_MARK, - .end = TRACE_REG_END_MARK - } -}; - -static struct trace_register_range trace_csi2_3ph_range_template[] = { - { - .start = TRACE_REG_CSI2_3PH_TM_RESET_REG_IDX, - .end = TRACE_REG_CSI2_3PH_TM_IRQ_ENABLE_REG_ID_N(7) - }, - { - .start = TRACE_REG_END_MARK, - .end = TRACE_REG_END_MARK - } -}; - -static struct trace_register_range trace_sig2cio_range_template[] = { - { - .start = TRACE_REG_SIG2CIO_ADDRESS, - .end = (TRACE_REG_SIG2CIO_STATUS + 8 * TRACE_REG_SIG2CIO_SIZE_OF) - }, - { - .start = TRACE_REG_END_MARK, - .end = TRACE_REG_END_MARK - } -}; - -#define LINE_MAX_LEN 128 #define MEMORY_RING_BUFFER_SIZE (SZ_1M * 32) #define TRACE_MESSAGE_SIZE 16 /* @@ -77,8 +32,6 @@ static struct trace_register_range trace_sig2cio_range_template[] = { #define MAX_TRACE_REGISTERS 200 #define TRACE_CONF_DUMP_BUFFER_SIZE (MAX_TRACE_REGISTERS * 2 * 32) -#define IPU_TRACE_TIME_RETRY 5 - struct config_value { u32 reg; u32 value; @@ -89,6 +42,14 @@ struct ipu_trace_buffer { void *memory_buffer; }; +struct ipu_subsystem_wptrace_config { + bool open; + char *conf_dump_buffer; + int size_conf_dump; + unsigned int fill_level; + struct config_value config[MAX_TRACE_REGISTERS]; +}; + struct ipu_subsystem_trace_config { u32 offset; void __iomem *base; @@ -99,16 +60,8 @@ struct ipu_subsystem_trace_config { bool running; /* Cached register values */ struct config_value config[MAX_TRACE_REGISTERS]; -}; - -/* - * State of the input data processing is kept in this structure. - * Only one user is supported at time. - */ -struct buf_state { - char line_buffer[LINE_MAX_LEN]; - enum config_file_parse_states state; - int offset; /* Offset to line_buffer */ + /* watchpoint trace info */ + struct ipu_subsystem_wptrace_config wpt; }; struct ipu_trace { @@ -116,7 +69,6 @@ struct ipu_trace { bool open; char *conf_dump_buffer; int size_conf_dump; - struct buf_state buffer_state; struct ipu_subsystem_trace_config isys; struct ipu_subsystem_trace_config psys; @@ -160,12 +112,11 @@ static void __ipu_trace_restore(struct device *dev) if (!sys->memory.memory_buffer) { sys->memory.memory_buffer = - dma_alloc_noncoherent(dev, - MEMORY_RING_BUFFER_SIZE + - MEMORY_RING_BUFFER_GUARD, - &sys->memory.dma_handle, - DMA_BIDIRECTIONAL, - GFP_KERNEL); + dma_alloc_coherent(dev, + MEMORY_RING_BUFFER_SIZE + + MEMORY_RING_BUFFER_GUARD, + &sys->memory.dma_handle, + GFP_KERNEL); } if (!sys->memory.memory_buffer) { @@ -213,6 +164,13 @@ static void __ipu_trace_restore(struct device *dev) writel(config[i].value, isp->base + config[i].reg); } + /* Register wpt config received from userspace, and only psys has wpt */ + config = sys->wpt.config; + for (i = 0; i < sys->wpt.fill_level; i++) { + dev_dbg(dev, "Trace restore: reg 0x%08x, value 0x%08x\n", + config[i].reg, config[i].value); + writel(config[i].value, isp->base + config[i].reg); + } sys->running = true; } @@ -291,51 +249,10 @@ void ipu_trace_stop(struct device *dev) } EXPORT_SYMBOL_GPL(ipu_trace_stop); -static int validate_register(u32 base, u32 reg, u16 *template) -{ - int i = 0; - - while (template[i] != TRACE_REG_END_MARK) { - if (template[i] + base != reg) { - i++; - continue; - } - /* This is a valid register */ - return 0; - } - return -EINVAL; -} - -static int validate_register_range(u32 base, u32 reg, - struct trace_register_range *template) -{ - unsigned int i = 0; - - if (!IS_ALIGNED(reg, sizeof(u32))) - return -EINVAL; - - while (template[i].start != TRACE_REG_END_MARK) { - if ((reg < template[i].start + base) || - (reg > template[i].end + base)) { - i++; - continue; - } - /* This is a valid register */ - return 0; - } - return -EINVAL; -} - static int update_register_cache(struct ipu_device *isp, u32 reg, u32 value) { struct ipu_trace *dctrl = isp->trace; - const struct ipu_trace_block *blocks; struct ipu_subsystem_trace_config *sys; - struct device *dev; - u32 base = 0; - u16 *template = NULL; - struct trace_register_range *template_range = NULL; - int i, range; int rval = -EINVAL; if (dctrl->isys.offset == dctrl->psys.offset) { @@ -361,55 +278,8 @@ static int update_register_cache(struct ipu_device *isp, u32 reg, u32 value) goto error; } - blocks = sys->blocks; - dev = sys->dev; - - /* Check registers block by block */ - i = 0; - while (blocks[i].type != IPU_TRACE_BLOCK_END) { - base = blocks[i].offset + sys->offset; - if ((reg >= base && reg < base + TRACE_REG_MAX_BLOCK_SIZE)) - break; - i++; - } - - range = 0; - switch (blocks[i].type) { - case IPU_TRACE_BLOCK_TUN: - template = trace_unit_template; - break; - case IPU_TRACE_BLOCK_TM: - template = trace_monitor_template; - break; - case IPU_TRACE_BLOCK_GPC: - template = trace_gpc_template; - break; - case IPU_TRACE_CSI2: - range = 1; - template_range = trace_csi2_range_template; - break; - case IPU_TRACE_CSI2_3PH: - range = 1; - template_range = trace_csi2_3ph_range_template; - break; - case IPU_TRACE_SIG2CIOS: - range = 1; - template_range = trace_sig2cio_range_template; - break; - default: - goto error; - } - - if (range) - rval = validate_register_range(base, reg, template_range); - else - rval = validate_register(base, reg, template); - - if (rval) - goto error; - if (sys->fill_level < MAX_TRACE_REGISTERS) { - dev_dbg(dev, + dev_dbg(sys->dev, "Trace reg addr 0x%08x value 0x%08x\n", reg, value); sys->config[sys->fill_level].reg = reg; sys->config[sys->fill_level].value = value; @@ -426,79 +296,6 @@ static int update_register_cache(struct ipu_device *isp, u32 reg, u32 value) return rval; } -/* - * We don't know how much data is received this time. Process given data - * character by character. - * Fill the line buffer until either - * 1) new line is got -> go to decode - * or - * 2) line_buffer is full -> ignore rest of line and then try to decode - * or - * 3) Comment mark is found -> ignore rest of the line and then try to decode - * the data which was received before the comment mark - * - * Decode phase tries to find "reg = value" pairs and validates those - */ -static int process_buffer(struct ipu_device *isp, - char *buffer, int size, struct buf_state *state) -{ - int i, ret; - int curr_state = state->state; - u32 reg, value; - - for (i = 0; i < size; i++) { - /* - * Comment mark in any position turns on comment mode - * until end of line - */ - if (curr_state != STATE_COMMENT && buffer[i] == '#') { - state->line_buffer[state->offset] = '\0'; - curr_state = STATE_COMMENT; - continue; - } - - switch (curr_state) { - case STATE_COMMENT: - /* Only new line can break this mode */ - if (buffer[i] == '\n') - curr_state = STATE_COMPLETE; - break; - case STATE_FILL: - state->line_buffer[state->offset] = buffer[i]; - state->offset++; - - if (state->offset >= sizeof(state->line_buffer) - 1) { - /* Line buffer full - ignore rest */ - state->line_buffer[state->offset] = '\0'; - curr_state = STATE_COMMENT; - break; - } - - if (buffer[i] == '\n') { - state->line_buffer[state->offset] = '\0'; - curr_state = STATE_COMPLETE; - } - break; - default: - state->offset = 0; - state->line_buffer[state->offset] = '\0'; - curr_state = STATE_COMMENT; - } - - if (curr_state == STATE_COMPLETE) { - ret = sscanf(state->line_buffer, "%x = %x", - ®, &value); - if (ret == 2) - update_register_cache(isp, reg, value); - - state->offset = 0; - curr_state = STATE_FILL; - } - } - state->state = curr_state; - return 0; -} - static void traceconf_dump(struct ipu_device *isp) { struct ipu_subsystem_trace_config *sys[2] = { @@ -570,6 +367,7 @@ static int traceconf_open(struct inode *inode, struct file *file) /* Forget old config if opened for write */ isp->trace->isys.fill_level = 0; isp->trace->psys.fill_level = 0; + isp->trace->psys.wpt.fill_level = 0; } if (file->f_mode & FMODE_READ) { @@ -599,26 +397,51 @@ static ssize_t traceconf_read(struct file *file, char __user *buf, static ssize_t traceconf_write(struct file *file, const char __user *buf, size_t len, loff_t *ppos) { + int i; struct ipu_device *isp = file->private_data; - char buffer[64]; - ssize_t bytes, count; - loff_t pos = *ppos; - - if (*ppos < 0) + ssize_t bytes = 0; + char *ipu_trace_buffer = NULL; + size_t buffer_size = 0; + u32 ipu_trace_number = 0; + struct config_value *cfg_buffer = NULL; + + if ((*ppos < 0) || (len < sizeof(ipu_trace_number))) { + dev_info(&isp->pdev->dev, + "length is error, len:%ld, loff:%lld\n", + len, *ppos); return -EINVAL; + } - count = min(len, sizeof(buffer)); - bytes = copy_from_user(buffer, buf, count); - if (bytes == count) + ipu_trace_buffer = vzalloc(len); + if (!ipu_trace_buffer) + return -ENOMEM; + + bytes = copy_from_user(ipu_trace_buffer, buf, len); + if (bytes != 0) { + vfree(ipu_trace_buffer); + return -EFAULT; + } + + memcpy(&ipu_trace_number, ipu_trace_buffer, sizeof(u32)); + buffer_size = ipu_trace_number * sizeof(struct config_value); + if ((buffer_size + sizeof(ipu_trace_number)) != len) { + dev_info(&isp->pdev->dev, + "File size is not right, len:%ld, buffer_size:%zu\n", + len, buffer_size); + vfree(ipu_trace_buffer); return -EFAULT; + } - count -= bytes; mutex_lock(&isp->trace->lock); - process_buffer(isp, buffer, count, &isp->trace->buffer_state); + cfg_buffer = (struct config_value *)(ipu_trace_buffer + sizeof(u32)); + for (i = 0; i < ipu_trace_number; i++) { + update_register_cache(isp, cfg_buffer[i].reg, + cfg_buffer[i].value); + } mutex_unlock(&isp->trace->lock); - *ppos = pos + count; + vfree(ipu_trace_buffer); - return count; + return len; } static int traceconf_release(struct inode *inode, struct file *file) @@ -697,6 +520,161 @@ static const struct file_operations ipu_traceconf_fops = { .llseek = no_llseek, }; +static void wptraceconf_dump(struct ipu_device *isp) +{ + struct ipu_subsystem_wptrace_config *sys = &isp->trace->psys.wpt; + int i, rem_size; + char *out; + + sys->size_conf_dump = 0; + out = sys->conf_dump_buffer; + rem_size = TRACE_CONF_DUMP_BUFFER_SIZE; + + for (i = 0; i < sys->fill_level && rem_size > 0; i++) { + int bytes_print; + int n = snprintf(out, rem_size, "0x%08x = 0x%08x\n", + sys->config[i].reg, + sys->config[i].value); + + bytes_print = min(n, rem_size - 1); + rem_size -= bytes_print; + out += bytes_print; + } + sys->size_conf_dump = out - sys->conf_dump_buffer; +} + +static int wptraceconf_open(struct inode *inode, struct file *file) +{ + int ret; + struct ipu_device *isp; + + if (!inode->i_private) + return -EACCES; + + isp = inode->i_private; + ret = mutex_trylock(&isp->trace->lock); + if (!ret) + return -EBUSY; + + if (isp->trace->psys.wpt.open) { + mutex_unlock(&isp->trace->lock); + return -EBUSY; + } + + file->private_data = isp; + if (file->f_mode & FMODE_WRITE) { + /* TBD: Allocate temp buffer for processing. + * Push validated buffer to active config + */ + /* Forget old config if opened for write */ + isp->trace->psys.wpt.fill_level = 0; + } + + if (file->f_mode & FMODE_READ) { + isp->trace->psys.wpt.conf_dump_buffer = + vzalloc(TRACE_CONF_DUMP_BUFFER_SIZE); + if (!isp->trace->psys.wpt.conf_dump_buffer) { + mutex_unlock(&isp->trace->lock); + return -ENOMEM; + } + wptraceconf_dump(isp); + } + mutex_unlock(&isp->trace->lock); + return 0; +} + +static ssize_t wptraceconf_read(struct file *file, char __user *buf, + size_t len, loff_t *ppos) +{ + struct ipu_device *isp = file->private_data; + + return simple_read_from_buffer(buf, len, ppos, + isp->trace->psys.wpt.conf_dump_buffer, + isp->trace->psys.wpt.size_conf_dump); +} + +static ssize_t wptraceconf_write(struct file *file, const char __user *buf, + size_t len, loff_t *ppos) +{ + int i; + struct ipu_device *isp = file->private_data; + ssize_t bytes = 0; + char *wpt_info_buffer = NULL; + size_t buffer_size = 0; + u32 wp_node_number = 0; + struct config_value *wpt_buffer = NULL; + struct ipu_subsystem_wptrace_config *wpt = &isp->trace->psys.wpt; + + if ((*ppos < 0) || (len < sizeof(wp_node_number))) { + dev_info(&isp->pdev->dev, + "length is error, len:%ld, loff:%lld\n", + len, *ppos); + return -EINVAL; + } + + wpt_info_buffer = vzalloc(len); + if (!wpt_info_buffer) + return -ENOMEM; + + bytes = copy_from_user(wpt_info_buffer, buf, len); + if (bytes != 0) { + vfree(wpt_info_buffer); + return -EFAULT; + } + + memcpy(&wp_node_number, wpt_info_buffer, sizeof(u32)); + buffer_size = wp_node_number * sizeof(struct config_value); + if ((buffer_size + sizeof(wp_node_number)) != len) { + dev_info(&isp->pdev->dev, + "File size is not right, len:%ld, buffer_size:%zu\n", + len, buffer_size); + vfree(wpt_info_buffer); + return -EFAULT; + } + + mutex_lock(&isp->trace->lock); + wpt_buffer = (struct config_value *)(wpt_info_buffer + sizeof(u32)); + for (i = 0; i < wp_node_number; i++) { + if (wpt->fill_level < MAX_TRACE_REGISTERS) { + wpt->config[wpt->fill_level].reg = wpt_buffer[i].reg; + wpt->config[wpt->fill_level].value = + wpt_buffer[i].value; + wpt->fill_level++; + } else { + dev_info(&isp->pdev->dev, + "Address 0x%08x ignored as invalid register\n", + wpt_buffer[i].reg); + break; + } + } + mutex_unlock(&isp->trace->lock); + vfree(wpt_info_buffer); + + return len; +} + +static int wptraceconf_release(struct inode *inode, struct file *file) +{ + struct ipu_device *isp = file->private_data; + + mutex_lock(&isp->trace->lock); + isp->trace->open = 0; + vfree(isp->trace->psys.wpt.conf_dump_buffer); + isp->trace->psys.wpt.conf_dump_buffer = NULL; + mutex_unlock(&isp->trace->lock); + + return 0; +} + +static const struct file_operations ipu_wptraceconf_fops = { + .owner = THIS_MODULE, + .open = wptraceconf_open, + .release = wptraceconf_release, + .read = wptraceconf_read, + .write = wptraceconf_write, + .llseek = no_llseek, +}; + static int gettrace_open(struct inode *inode, struct file *file) { struct ipu_subsystem_trace_config *sys = inode->i_private; @@ -812,11 +790,11 @@ void ipu_trace_uninit(struct device *dev) mutex_lock(&trace->lock); if (sys->memory.memory_buffer) - dma_free_noncoherent(sys->dev, - MEMORY_RING_BUFFER_SIZE + MEMORY_RING_BUFFER_GUARD, - sys->memory.memory_buffer, - sys->memory.dma_handle, - DMA_BIDIRECTIONAL); + dma_free_coherent(sys->dev, + MEMORY_RING_BUFFER_SIZE + + MEMORY_RING_BUFFER_GUARD, + sys->memory.memory_buffer, + sys->memory.dma_handle); sys->dev = NULL; sys->memory.memory_buffer = NULL; @@ -827,7 +805,7 @@ EXPORT_SYMBOL_GPL(ipu_trace_uninit); int ipu_trace_debugfs_add(struct ipu_device *isp, struct dentry *dir) { - struct dentry *files[3]; + struct dentry *files[4]; int i = 0; files[i] = debugfs_create_file("traceconf", 0644, @@ -836,6 +814,12 @@ int ipu_trace_debugfs_add(struct ipu_device *isp, struct dentry *dir) return -ENOMEM; i++; + files[i] = debugfs_create_file("wptraceconf", 0644, + dir, isp, &ipu_wptraceconf_fops); + if (!files[i]) + goto error; + i++; + files[i] = debugfs_create_file("getisystrace", 0444, dir, &isp->trace->isys, &ipu_gettrace_fops); diff --git a/drivers/media/pci/intel/ipu-trace.h b/drivers/media/pci/intel/ipu-trace.h index f66b63aacc9a..f1233a306519 100644 --- a/drivers/media/pci/intel/ipu-trace.h +++ b/drivers/media/pci/intel/ipu-trace.h @@ -1,19 +1,10 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (C) 2014 - 2020 Intel Corporation */ +/* Copyright (C) 2014 - 2021 Intel Corporation */ #ifndef IPU_TRACE_H #define IPU_TRACE_H #include -#define TRACE_REG_MAX_BLOCK_SIZE 0x0fff - -#define TRACE_REG_END_MARK 0xffff - -#define TRACE_REG_CMD_TYPE_D64 0x0 -#define TRACE_REG_CMD_TYPE_D64M 0x1 -#define TRACE_REG_CMD_TYPE_D64TS 0x2 -#define TRACE_REG_CMD_TYPE_D64MTS 0x3 - /* Trace unit register offsets */ #define TRACE_REG_TUN_DDR_ENABLE 0x000 #define TRACE_REG_TUN_NPK_ENABLE 0x004 @@ -26,14 +17,6 @@ #define TRACE_REG_TUN_WR_PTR 0x020 #define TRACE_REG_TUN_RD_PTR 0x024 -#define TRACE_REG_CREATE_TUN_REGISTER_LIST { \ - TRACE_REG_TUN_DDR_ENABLE, \ - TRACE_REG_TUN_NPK_ENABLE, \ - TRACE_REG_TUN_DDR_INFO_VAL, \ - TRACE_REG_TUN_NPK_ADDR, \ - TRACE_REG_END_MARK \ -} - /* * Following registers are left out on purpose: * TUN_LOCAL_TIMER0, TUN_LOCAL_TIMER1, TUN_DRAM_BASE_ADDR @@ -69,34 +52,6 @@ #define TRACE_REG_TM_FWTRACE_MIDDLE 0x0A04 #define TRACE_REG_TM_FWTRACE_LAST 0x0A08 -#define TRACE_REG_CREATE_TM_REGISTER_LIST { \ - TRACE_REG_TM_TRACE_ADDR_A, \ - TRACE_REG_TM_TRACE_ADDR_B, \ - TRACE_REG_TM_TRACE_ADDR_C, \ - TRACE_REG_TM_TRACE_ADDR_D, \ - TRACE_REG_TM_TRACE_ENABLE_NPK, \ - TRACE_REG_TM_TRACE_ENABLE_DDR, \ - TRACE_REG_TM_TRACE_PER_PC, \ - TRACE_REG_TM_TRACE_PER_BRANCH, \ - TRACE_REG_TM_TRACE_HEADER, \ - TRACE_REG_TM_TRACE_CFG, \ - TRACE_REG_TM_TRACE_LOST_PACKETS, \ - TRACE_REG_TM_TRACE_LP_CLEAR, \ - TRACE_REG_TM_TRACE_LMRUN_MASK, \ - TRACE_REG_TM_TRACE_LMRUN_PC_LOW, \ - TRACE_REG_TM_TRACE_LMRUN_PC_HIGH, \ - TRACE_REG_TM_TRACE_MMIO_SEL, \ - TRACE_REG_TM_TRACE_MMIO_WP0_LOW, \ - TRACE_REG_TM_TRACE_MMIO_WP1_LOW, \ - TRACE_REG_TM_TRACE_MMIO_WP2_LOW, \ - TRACE_REG_TM_TRACE_MMIO_WP3_LOW, \ - TRACE_REG_TM_TRACE_MMIO_WP0_HIGH, \ - TRACE_REG_TM_TRACE_MMIO_WP1_HIGH, \ - TRACE_REG_TM_TRACE_MMIO_WP2_HIGH, \ - TRACE_REG_TM_TRACE_MMIO_WP3_HIGH, \ - TRACE_REG_END_MARK \ -} - /* * Following exists only in (I)SP address space: * TM_FWTRACE_FIRST, TM_FWTRACE_MIDDLE, TM_FWTRACE_LAST @@ -161,127 +116,6 @@ #define TRACE_REG_GPC_IRQ_ENABLE_ID2 0x0b8 #define TRACE_REG_GPC_IRQ_ENABLE_ID3 0x0bc -#define TRACE_REG_CREATE_GPC_REGISTER_LIST { \ - TRACE_REG_GPC_RESET, \ - TRACE_REG_GPC_OVERALL_ENABLE, \ - TRACE_REG_GPC_TRACE_HEADER, \ - TRACE_REG_GPC_TRACE_ADDRESS, \ - TRACE_REG_GPC_TRACE_NPK_EN, \ - TRACE_REG_GPC_TRACE_DDR_EN, \ - TRACE_REG_GPC_TRACE_LPKT_CLEAR, \ - TRACE_REG_GPC_TRACE_LPKT, \ - TRACE_REG_GPC_ENABLE_ID0, \ - TRACE_REG_GPC_ENABLE_ID1, \ - TRACE_REG_GPC_ENABLE_ID2, \ - TRACE_REG_GPC_ENABLE_ID3, \ - TRACE_REG_GPC_VALUE_ID0, \ - TRACE_REG_GPC_VALUE_ID1, \ - TRACE_REG_GPC_VALUE_ID2, \ - TRACE_REG_GPC_VALUE_ID3, \ - TRACE_REG_GPC_CNT_INPUT_SELECT_ID0, \ - TRACE_REG_GPC_CNT_INPUT_SELECT_ID1, \ - TRACE_REG_GPC_CNT_INPUT_SELECT_ID2, \ - TRACE_REG_GPC_CNT_INPUT_SELECT_ID3, \ - TRACE_REG_GPC_CNT_START_SELECT_ID0, \ - TRACE_REG_GPC_CNT_START_SELECT_ID1, \ - TRACE_REG_GPC_CNT_START_SELECT_ID2, \ - TRACE_REG_GPC_CNT_START_SELECT_ID3, \ - TRACE_REG_GPC_CNT_STOP_SELECT_ID0, \ - TRACE_REG_GPC_CNT_STOP_SELECT_ID1, \ - TRACE_REG_GPC_CNT_STOP_SELECT_ID2, \ - TRACE_REG_GPC_CNT_STOP_SELECT_ID3, \ - TRACE_REG_GPC_CNT_MSG_SELECT_ID0, \ - TRACE_REG_GPC_CNT_MSG_SELECT_ID1, \ - TRACE_REG_GPC_CNT_MSG_SELECT_ID2, \ - TRACE_REG_GPC_CNT_MSG_SELECT_ID3, \ - TRACE_REG_GPC_CNT_MSG_PLOAD_SELECT_ID0, \ - TRACE_REG_GPC_CNT_MSG_PLOAD_SELECT_ID1, \ - TRACE_REG_GPC_CNT_MSG_PLOAD_SELECT_ID2, \ - TRACE_REG_GPC_CNT_MSG_PLOAD_SELECT_ID3, \ - TRACE_REG_GPC_IRQ_TRIGGER_VALUE_ID0, \ - TRACE_REG_GPC_IRQ_TRIGGER_VALUE_ID1, \ - TRACE_REG_GPC_IRQ_TRIGGER_VALUE_ID2, \ - TRACE_REG_GPC_IRQ_TRIGGER_VALUE_ID3, \ - TRACE_REG_GPC_IRQ_TIMER_SELECT_ID0, \ - TRACE_REG_GPC_IRQ_TIMER_SELECT_ID1, \ - TRACE_REG_GPC_IRQ_TIMER_SELECT_ID2, \ - TRACE_REG_GPC_IRQ_TIMER_SELECT_ID3, \ - TRACE_REG_GPC_IRQ_ENABLE_ID0, \ - TRACE_REG_GPC_IRQ_ENABLE_ID1, \ - TRACE_REG_GPC_IRQ_ENABLE_ID2, \ - TRACE_REG_GPC_IRQ_ENABLE_ID3, \ - TRACE_REG_END_MARK \ -} - -/* CSI2 legacy receiver trace registers */ -#define TRACE_REG_CSI2_TM_RESET_REG_IDX 0x0000 -#define TRACE_REG_CSI2_TM_OVERALL_ENABLE_REG_IDX 0x0004 -#define TRACE_REG_CSI2_TM_TRACE_HEADER_REG_IDX 0x0008 -#define TRACE_REG_CSI2_TM_TRACE_ADDRESS_REG_IDX 0x000c -#define TRACE_REG_CSI2_TM_TRACE_HEADER_VAL 0xf -#define TRACE_REG_CSI2_TM_TRACE_ADDRESS_VAL 0x100218 -#define TRACE_REG_CSI2_TM_MONITOR_ID 0x8 - -/* 0 <= n <= 3 */ -#define TRACE_REG_CSI2_TM_TRACE_NPK_EN_REG_IDX_P(n) (0x0010 + (n) * 4) -#define TRACE_REG_CSI2_TM_TRACE_DDR_EN_REG_IDX_P(n) (0x0020 + (n) * 4) -#define TRACE_CSI2_TM_EVENT_FE(vc) (BIT(0) << ((vc) * 6)) -#define TRACE_CSI2_TM_EVENT_FS(vc) (BIT(1) << ((vc) * 6)) -#define TRACE_CSI2_TM_EVENT_PE(vc) (BIT(2) << ((vc) * 6)) -#define TRACE_CSI2_TM_EVENT_PS(vc) (BIT(3) << ((vc) * 6)) -#define TRACE_CSI2_TM_EVENT_LE(vc) (BIT(4) << ((vc) * 6)) -#define TRACE_CSI2_TM_EVENT_LS(vc) (BIT(5) << ((vc) * 6)) - -#define TRACE_REG_CSI2_TM_TRACE_LPKT_CLEAR_REG_IDX 0x0030 -#define TRACE_REG_CSI2_TM_TRACE_LPKT_REG_IDX 0x0034 - -/* 0 <= n <= 7 */ -#define TRACE_REG_CSI2_TM_ENABLE_REG_ID_N(n) (0x0038 + (n) * 4) -#define TRACE_REG_CSI2_TM_VALUE_REG_ID_N(n) (0x0058 + (n) * 4) -#define TRACE_REG_CSI2_TM_CNT_INPUT_SELECT_REG_ID_N(n) (0x0078 + (n) * 4) -#define TRACE_REG_CSI2_TM_CNT_START_SELECT_REG_ID_N(n) (0x0098 + (n) * 4) -#define TRACE_REG_CSI2_TM_CNT_STOP_SELECT_REG_ID_N(n) (0x00b8 + (n) * 4) -#define TRACE_REG_CSI2_TM_IRQ_TRIGGER_VALUE_REG_ID_N(n) (0x00d8 + (n) * 4) -#define TRACE_REG_CSI2_TM_IRQ_TIMER_SELECT_REG_ID_N(n) (0x00f8 + (n) * 4) -#define TRACE_REG_CSI2_TM_IRQ_ENABLE_REG_ID_N(n) (0x0118 + (n) * 4) - -/* CSI2_3PH combo receiver trace registers */ -#define TRACE_REG_CSI2_3PH_TM_RESET_REG_IDX 0x0000 -#define TRACE_REG_CSI2_3PH_TM_OVERALL_ENABLE_REG_IDX 0x0004 -#define TRACE_REG_CSI2_3PH_TM_TRACE_HEADER_REG_IDX 0x0008 -#define TRACE_REG_CSI2_3PH_TM_TRACE_ADDRESS_REG_IDX 0x000c -#define TRACE_REG_CSI2_3PH_TM_TRACE_ADDRESS_VAL 0x100258 -#define TRACE_REG_CSI2_3PH_TM_MONITOR_ID 0x9 - -/* 0 <= n <= 5 */ -#define TRACE_REG_CSI2_3PH_TM_TRACE_NPK_EN_REG_IDX_P(n) (0x0010 + (n) * 4) -#define TRACE_REG_CSI2_3PH_TM_TRACE_DDR_EN_REG_IDX_P(n) (0x0028 + (n) * 4) - -#define TRACE_REG_CSI2_3PH_TM_TRACE_LPKT_CLEAR_REG_IDX 0x0040 -#define TRACE_REG_CSI2_3PH_TM_TRACE_LPKT_REG_IDX 0x0044 - -/* 0 <= n <= 7 */ -#define TRACE_REG_CSI2_3PH_TM_ENABLE_REG_ID_N(n) (0x0048 + (n) * 4) -#define TRACE_REG_CSI2_3PH_TM_VALUE_REG_ID_N(n) (0x0068 + (n) * 4) -#define TRACE_REG_CSI2_3PH_TM_CNT_INPUT_SELECT_REG_ID_N(n) (0x0088 + (n) * 4) -#define TRACE_REG_CSI2_3PH_TM_CNT_START_SELECT_REG_ID_N(n) (0x00a8 + (n) * 4) -#define TRACE_REG_CSI2_3PH_TM_CNT_STOP_SELECT_REG_ID_N(n) (0x00c8 + (n) * 4) -#define TRACE_REG_CSI2_3PH_TM_IRQ_TRIGGER_VALUE_REG_ID_N(n) (0x00e8 + (n) * 4) -#define TRACE_REG_CSI2_3PH_TM_IRQ_TIMER_SELECT_REG_ID_N(n) (0x0108 + (n) * 4) -#define TRACE_REG_CSI2_3PH_TM_IRQ_ENABLE_REG_ID_N(n) (0x0128 + (n) * 4) - -/* SIG2CIO trace monitors */ -#define TRACE_REG_SIG2CIO_ADDRESS 0x0000 -#define TRACE_REG_SIG2CIO_WDATA 0x0004 -#define TRACE_REG_SIG2CIO_MASK 0x0008 -#define TRACE_REG_SIG2CIO_GROUP_CFG 0x000c -#define TRACE_REG_SIG2CIO_STICKY 0x0010 -#define TRACE_REG_SIG2CIO_RST_STICKY 0x0014 -#define TRACE_REG_SIG2CIO_MANUAL_RST_STICKY 0x0018 -#define TRACE_REG_SIG2CIO_STATUS 0x001c -/* Size of on SIG2CIO block */ -#define TRACE_REG_SIG2CIO_SIZE_OF 0x0020 - struct ipu_trace; struct ipu_subsystem_trace_config; diff --git a/drivers/media/pci/intel/ipu.c b/drivers/media/pci/intel/ipu.c index 40d7268615b1..f7826d07ea54 100644 --- a/drivers/media/pci/intel/ipu.c +++ b/drivers/media/pci/intel/ipu.c @@ -283,19 +283,22 @@ static void ipu_remove_debugfs(struct ipu_device *isp) static int ipu_pci_config_setup(struct pci_dev *dev) { u16 pci_command; - int rval = pci_enable_msi(dev); - - if (rval) { - dev_err(&dev->dev, "Failed to enable msi (%d)\n", rval); - return rval; - } + int rval; pci_read_config_word(dev, PCI_COMMAND, &pci_command); - pci_command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | - PCI_COMMAND_INTX_DISABLE; + pci_command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; pci_write_config_word(dev, PCI_COMMAND, pci_command); + if (ipu_ver == IPU_VER_6EP) { + /* likely do nothing as msi not enabled by default */ + pci_disable_msi(dev); + return 0; + } - return 0; + rval = pci_enable_msi(dev); + if (rval) + dev_err(&dev->dev, "Failed to enable msi (%d)\n", rval); + + return rval; } static void ipu_configure_vc_mechanism(struct ipu_device *isp) @@ -412,6 +415,10 @@ static int ipu_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) ipu_ver = IPU_VER_6SE; isp->cpd_fw_name = IPU6SE_FIRMWARE_NAME; break; + case IPU6EP_PCI_ID: + ipu_ver = IPU_VER_6EP; + isp->cpd_fw_name = IPU6EP_FIRMWARE_NAME; + break; default: WARN(1, "Unsupported IPU device"); return -ENODEV; @@ -743,6 +750,7 @@ static const struct dev_pm_ops ipu_pm_ops = { static const struct pci_device_id ipu_pci_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, IPU6_PCI_ID)}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, IPU6SE_PCI_ID)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, IPU6EP_PCI_ID)}, {0,} }; MODULE_DEVICE_TABLE(pci, ipu_pci_tbl); diff --git a/drivers/media/pci/intel/ipu.h b/drivers/media/pci/intel/ipu.h index 67b0561105e2..2b8758ccab9b 100644 --- a/drivers/media/pci/intel/ipu.h +++ b/drivers/media/pci/intel/ipu.h @@ -16,11 +16,13 @@ #define IPU6_PCI_ID 0x9a19 #define IPU6SE_PCI_ID 0x4e19 +#define IPU6EP_PCI_ID 0x465d enum ipu_version { IPU_VER_INVALID = 0, IPU_VER_6, IPU_VER_6SE, + IPU_VER_6EP, }; /* diff --git a/drivers/media/pci/intel/ipu6/Makefile b/drivers/media/pci/intel/ipu6/Makefile index 2bb2db666f7e..16ce80bff412 100644 --- a/drivers/media/pci/intel/ipu6/Makefile +++ b/drivers/media/pci/intel/ipu6/Makefile @@ -33,9 +33,7 @@ intel-ipu6-isys-objs += ../ipu-isys.o \ ../ipu-isys-queue.o \ ../ipu-isys-subdev.o -ifdef CONFIG_VIDEO_INTEL_IPU_TPG intel-ipu6-isys-objs += ../ipu-isys-tpg.o -endif obj-$(CONFIG_VIDEO_INTEL_IPU6) += intel-ipu6-isys.o @@ -49,6 +47,7 @@ intel-ipu6-psys-objs += ../ipu-psys.o \ intel-ipu6-psys-objs += ipu-fw-resources.o \ ipu6-fw-resources.o \ ipu6se-fw-resources.o \ + ipu6ep-fw-resources.o \ ../ipu-fw-psys.o ifeq ($(CONFIG_COMPAT),y) diff --git a/drivers/media/pci/intel/ipu6/ipu-platform-regs.h b/drivers/media/pci/intel/ipu6/ipu-platform-regs.h index 5415b7e46fe7..be6c7f298e6d 100644 --- a/drivers/media/pci/intel/ipu6/ipu-platform-regs.h +++ b/drivers/media/pci/intel/ipu6/ipu-platform-regs.h @@ -7,7 +7,7 @@ /* * IPU6 uses uniform address within IPU, therefore all subsystem registers * locates in one signle space starts from 0 but in different sctions with - * with different addresses, the subsystem offsets are defined to 0 as the + * different addresses, the subsystem offsets are defined to 0 as the * register definition will have the address offset to 0. */ #define IPU_UNIFIED_OFFSET 0 diff --git a/drivers/media/pci/intel/ipu6/ipu-platform-resources.h b/drivers/media/pci/intel/ipu6/ipu-platform-resources.h index f59d5fa86b01..1f3554c0e5af 100644 --- a/drivers/media/pci/intel/ipu6/ipu-platform-resources.h +++ b/drivers/media/pci/intel/ipu6/ipu-platform-resources.h @@ -98,5 +98,6 @@ void ipu_psys_free_cmd_queue_resource(struct ipu_psys_resource_pool *pool, extern const struct ipu_fw_resource_definitions *ipu6_res_defs; extern const struct ipu_fw_resource_definitions *ipu6se_res_defs; +extern const struct ipu_fw_resource_definitions *ipu6ep_res_defs; extern struct ipu6_psys_hw_res_variant hw_var; #endif /* IPU_PLATFORM_RESOURCES_COMMON_H */ diff --git a/drivers/media/pci/intel/ipu6/ipu-platform.h b/drivers/media/pci/intel/ipu6/ipu-platform.h index 62df421fa4d7..dfb3d570ed6b 100644 --- a/drivers/media/pci/intel/ipu6/ipu-platform.h +++ b/drivers/media/pci/intel/ipu6/ipu-platform.h @@ -7,6 +7,7 @@ #define IPU_NAME "intel-ipu6" #define IPU6SE_FIRMWARE_NAME "intel/ipu6se_fw.bin" +#define IPU6EP_FIRMWARE_NAME "intel/ipu6ep_fw.bin" #define IPU6_FIRMWARE_NAME "intel/ipu6_fw.bin" /* diff --git a/drivers/media/pci/intel/ipu6/ipu-resources.c b/drivers/media/pci/intel/ipu6/ipu-resources.c index 5a2dd03a85c5..41c634b04837 100644 --- a/drivers/media/pci/intel/ipu6/ipu-resources.c +++ b/drivers/media/pci/intel/ipu6/ipu-resources.c @@ -33,6 +33,15 @@ void ipu6_psys_hw_res_variant_init(void) hw_var.get_pgm_by_proc = ipu6_fw_psys_get_program_manifest_by_process; return; + } else if (ipu_ver == IPU_VER_6EP) { + hw_var.queue_num = IPU6_FW_PSYS_N_PSYS_CMD_QUEUE_ID; + hw_var.cell_num = IPU6EP_FW_PSYS_N_CELL_ID; + hw_var.set_proc_dev_chn = ipu6_fw_psys_set_proc_dev_chn; + hw_var.set_proc_dfm_bitmap = ipu6_fw_psys_set_proc_dfm_bitmap; + hw_var.set_proc_ext_mem = ipu6_fw_psys_set_process_ext_mem; + hw_var.get_pgm_by_proc = + ipu6_fw_psys_get_program_manifest_by_process; + return; } WARN(1, "ipu6 psys res var is not initialised correctly."); @@ -43,6 +52,9 @@ static const struct ipu_fw_resource_definitions *get_res(void) if (ipu_ver == IPU_VER_6SE) return ipu6se_res_defs; + if (ipu_ver == IPU_VER_6EP) + return ipu6ep_res_defs; + return ipu6_res_defs; } diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c b/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c index 86d895e0640c..b0f39586256b 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c +++ b/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c @@ -71,8 +71,8 @@ static int ipu6_csi2_phy_power_set(struct ipu_isys *isys, dev_dbg(&isys->adev->dev, "for phy %d port %d, lanes: %d\n", phy_id, port, cfg->nlanes); - nr = (ipu_ver == IPU_VER_6) ? IPU6_ISYS_CSI_PORT_NUM : - IPU6SE_ISYS_CSI_PORT_NUM; + nr = (ipu_ver == IPU_VER_6 || ipu_ver == IPU_VER_6EP) ? + IPU6_ISYS_CSI_PORT_NUM : IPU6SE_ISYS_CSI_PORT_NUM; if (!isys_base || port >= nr) { dev_warn(&isys->adev->dev, "invalid port ID %d\n", port); @@ -123,8 +123,8 @@ static void ipu6_isys_register_errors(struct ipu_isys_csi2 *csi2) u32 irq = readl(csi2->base + CSI_PORT_REG_BASE_IRQ_CSI + CSI_PORT_REG_BASE_IRQ_STATUS_OFFSET); - mask = (ipu_ver == IPU_VER_6) ? IPU6_CSI_RX_ERROR_IRQ_MASK : - IPU6SE_CSI_RX_ERROR_IRQ_MASK; + mask = (ipu_ver == IPU_VER_6 || ipu_ver == IPU_VER_6EP) ? + IPU6_CSI_RX_ERROR_IRQ_MASK : IPU6SE_CSI_RX_ERROR_IRQ_MASK; writel(irq & mask, csi2->base + CSI_PORT_REG_BASE_IRQ_CSI + @@ -351,8 +351,8 @@ int ipu_isys_csi2_set_stream(struct v4l2_subdev *sd, port = cfg->port; dev_dbg(&isys->adev->dev, "for port %u\n", port); - mask = (ipu_ver == IPU_VER_6) ? IPU6_CSI_RX_ERROR_IRQ_MASK : - IPU6SE_CSI_RX_ERROR_IRQ_MASK; + mask = (ipu_ver == IPU_VER_6 || ipu_ver == IPU_VER_6EP) ? + IPU6_CSI_RX_ERROR_IRQ_MASK : IPU6SE_CSI_RX_ERROR_IRQ_MASK; if (!enable) { @@ -386,7 +386,7 @@ int ipu_isys_csi2_set_stream(struct v4l2_subdev *sd, return ipu6_csi2_phy_power_set(isys, cfg, false); } - if (ipu_ver == IPU_VER_6) { + if (ipu_ver == IPU_VER_6 || ipu_ver == IPU_VER_6EP) { /* Enable DPHY power */ ret = ipu6_csi2_phy_power_set(isys, cfg, true); if (ret) { diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys.c b/drivers/media/pci/intel/ipu6/ipu6-isys.c index 28c45f433e2f..bc13affa8e5f 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-isys.c +++ b/drivers/media/pci/intel/ipu6/ipu6-isys.c @@ -8,9 +8,7 @@ #include "ipu-platform-regs.h" #include "ipu-trace.h" #include "ipu-isys.h" -#ifdef CONFIG_VIDEO_INTEL_IPU_TPG #include "ipu-isys-tpg.h" -#endif #include "ipu-platform-isys-csi2-reg.h" const struct ipu_isys_pixelformat ipu_isys_pfmts[] = { @@ -88,8 +86,8 @@ void isys_setup_hw(struct ipu_isys *isys) u32 irqs = 0; unsigned int i, nr; - nr = (ipu_ver == IPU_VER_6) ? IPU6_ISYS_CSI_PORT_NUM : - IPU6SE_ISYS_CSI_PORT_NUM; + nr = (ipu_ver == IPU_VER_6 || ipu_ver == IPU_VER_6EP) ? + IPU6_ISYS_CSI_PORT_NUM : IPU6SE_ISYS_CSI_PORT_NUM; /* Enable irqs for all MIPI ports */ for (i = 0; i < nr; i++) @@ -175,7 +173,6 @@ irqreturn_t isys_isr(struct ipu_bus_device *adev) return IRQ_HANDLED; } -#ifdef CONFIG_VIDEO_INTEL_IPU_TPG void ipu_isys_tpg_sof_event(struct ipu_isys_tpg *tpg) { struct ipu_isys_pipeline *ip = NULL; @@ -186,8 +183,8 @@ void ipu_isys_tpg_sof_event(struct ipu_isys_tpg *tpg) unsigned long flags; unsigned int i, nr; - nr = (ipu_ver == IPU_VER_6) ? IPU6_ISYS_CSI_PORT_NUM : - IPU6SE_ISYS_CSI_PORT_NUM; + nr = (ipu_ver == IPU_VER_6 || ipu_ver == IPU_VER_6EP) ? + IPU6_ISYS_CSI_PORT_NUM : IPU6SE_ISYS_CSI_PORT_NUM; spin_lock_irqsave(&tpg->isys->lock, flags); for (i = 0; i < nr; i++) { @@ -221,8 +218,8 @@ void ipu_isys_tpg_eof_event(struct ipu_isys_tpg *tpg) unsigned int i, nr; u32 frame_sequence; - nr = (ipu_ver == IPU_VER_6) ? IPU6_ISYS_CSI_PORT_NUM : - IPU6SE_ISYS_CSI_PORT_NUM; + nr = (ipu_ver == IPU_VER_6 || ipu_ver == IPU_VER_6EP) ? + IPU6_ISYS_CSI_PORT_NUM : IPU6SE_ISYS_CSI_PORT_NUM; spin_lock_irqsave(&tpg->isys->lock, flags); for (i = 0; i < nr; i++) { @@ -319,4 +316,3 @@ int tpg_set_stream(struct v4l2_subdev *sd, int enable) writel(2, tpg->base + MIPI_GEN_REG_COM_ENABLE); return 0; } -#endif diff --git a/drivers/media/pci/intel/ipu6/ipu6-l-scheduler.c b/drivers/media/pci/intel/ipu6/ipu6-l-scheduler.c index 3d3cd0c0841f..77677ef75ae7 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-l-scheduler.c +++ b/drivers/media/pci/intel/ipu6/ipu6-l-scheduler.c @@ -113,32 +113,38 @@ void ipu_psys_scheduler_add_kppg(struct ipu_psys_ppg *kppg, static int ipu_psys_detect_resource_contention(struct ipu_psys_ppg *kppg) { - struct ipu_psys_resource_pool try_res_pool; + struct ipu_psys_resource_pool *try_res_pool; struct ipu_psys *psys = kppg->fh->psys; - int ret; + int ret = 0; int state; + try_res_pool = kzalloc(sizeof(*try_res_pool), GFP_KERNEL); + if (IS_ERR_OR_NULL(try_res_pool)) + return -ENOMEM; + mutex_lock(&kppg->mutex); state = kppg->state; mutex_unlock(&kppg->mutex); if (state == PPG_STATE_STARTED || state == PPG_STATE_RUNNING || state == PPG_STATE_RESUMED) - return 0; + goto exit; - ret = ipu_psys_resource_pool_init(&try_res_pool); + ret = ipu_psys_resource_pool_init(try_res_pool); if (ret < 0) { dev_err(&psys->adev->dev, "unable to alloc pg resources\n"); WARN_ON(1); - return ret; + goto exit; } - ipu_psys_resource_copy(&psys->resource_pool_running, &try_res_pool); + ipu_psys_resource_copy(&psys->resource_pool_running, try_res_pool); ret = ipu_psys_try_allocate_resources(&psys->adev->dev, kppg->kpg->pg, kppg->manifest, - &try_res_pool); + try_res_pool); - ipu_psys_resource_pool_cleanup(&try_res_pool); + ipu_psys_resource_pool_cleanup(try_res_pool); +exit: + kfree(try_res_pool); return ret; } @@ -370,29 +376,27 @@ static void ipu_psys_update_ppg_state_by_kcmd(struct ipu_psys *psys, if (kppg->state == PPG_STATE_STARTED || kppg->state == PPG_STATE_RESUMED || kppg->state == PPG_STATE_RUNNING) { - if (kcmd->state == KCMD_STATE_PPG_START) { + if (kcmd->state == KCMD_STATE_PPG_START) ipu_psys_kcmd_complete(kppg, kcmd, 0); - } else if (kcmd->state == KCMD_STATE_PPG_STOP) { + else if (kcmd->state == KCMD_STATE_PPG_STOP) kppg->state = PPG_STATE_STOP; - } } else if (kppg->state == PPG_STATE_SUSPENDED) { - if (kcmd->state == KCMD_STATE_PPG_START) { + if (kcmd->state == KCMD_STATE_PPG_START) ipu_psys_kcmd_complete(kppg, kcmd, 0); - } else if (kcmd->state == KCMD_STATE_PPG_STOP) { + else if (kcmd->state == KCMD_STATE_PPG_STOP) /* * Record the previous state * because here need resume at first */ kppg->state |= PPG_STATE_STOP; - } else if (kcmd->state == KCMD_STATE_PPG_ENQUEUE) { + else if (kcmd->state == KCMD_STATE_PPG_ENQUEUE) kppg->state = PPG_STATE_RESUME; - } } else if (kppg->state == PPG_STATE_STOPPED) { - if (kcmd->state == KCMD_STATE_PPG_START) { + if (kcmd->state == KCMD_STATE_PPG_START) kppg->state = PPG_STATE_START; - } else if (kcmd->state == KCMD_STATE_PPG_STOP) { + else if (kcmd->state == KCMD_STATE_PPG_STOP) ipu_psys_kcmd_complete(kppg, kcmd, 0); - } else if (kcmd->state == KCMD_STATE_PPG_ENQUEUE) { + else if (kcmd->state == KCMD_STATE_PPG_ENQUEUE) { dev_err(&psys->adev->dev, "ppg %p stopped!\n", kppg); ipu_psys_kcmd_complete(kppg, kcmd, -EIO); } diff --git a/drivers/media/pci/intel/ipu6/ipu6-platform-resources.h b/drivers/media/pci/intel/ipu6/ipu6-platform-resources.h index b8725e4551cf..07d4b4e688fb 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-platform-resources.h +++ b/drivers/media/pci/intel/ipu6/ipu6-platform-resources.h @@ -158,7 +158,7 @@ enum { #define IPU6_FW_PSYS_DEV_CHN_DMA_EXT0_MAX_SIZE 30 #define IPU6_FW_PSYS_DEV_CHN_GDC_MAX_SIZE 0 #define IPU6_FW_PSYS_DEV_CHN_DMA_EXT1_READ_MAX_SIZE 30 -#define IPU6_FW_PSYS_DEV_CHN_DMA_EXT1_WRITE_MAX_SIZE 37 +#define IPU6_FW_PSYS_DEV_CHN_DMA_EXT1_WRITE_MAX_SIZE 43 #define IPU6_FW_PSYS_DEV_CHN_DMA_INTERNAL_MAX_SIZE 8 #define IPU6_FW_PSYS_DEV_CHN_DMA_IPFD_MAX_SIZE 0 #define IPU6_FW_PSYS_DEV_CHN_DMA_ISA_MAX_SIZE 2 diff --git a/drivers/media/pci/intel/ipu6/ipu6.c b/drivers/media/pci/intel/ipu6/ipu6.c index da33bc952624..eb59eaa47413 100644 --- a/drivers/media/pci/intel/ipu6/ipu6.c +++ b/drivers/media/pci/intel/ipu6/ipu6.c @@ -58,7 +58,6 @@ static unsigned int ipu6se_csi_offsets[] = { IPU_CSI_PORT_D_ADDR_OFFSET, }; -#ifdef CONFIG_VIDEO_INTEL_IPU_TPG static unsigned int ipu6se_tpg_offsets[] = { IPU_CSI_PORT_A_PIXGEN_ADDR_OFFSET, IPU_CSI_PORT_B_PIXGEN_ADDR_OFFSET, @@ -76,7 +75,6 @@ static unsigned int ipu6_tpg_offsets[] = { IPU_CSI_PORT_G_PIXGEN_ADDR_OFFSET, IPU_CSI_PORT_H_PIXGEN_ADDR_OFFSET }; -#endif static unsigned int ipu6_csi_offsets[] = { IPU_CSI_PORT_A_ADDR_OFFSET, @@ -343,25 +341,21 @@ int ipu_buttress_psys_freq_get(void *data, u64 *val) void ipu_internal_pdata_init(void) { - if (ipu_ver == IPU_VER_6) { + if (ipu_ver == IPU_VER_6 || ipu_ver == IPU_VER_6EP) { isys_ipdata.csi2.nports = ARRAY_SIZE(ipu6_csi_offsets); isys_ipdata.csi2.offsets = ipu6_csi_offsets; -#ifdef CONFIG_VIDEO_INTEL_IPU_TPG isys_ipdata.tpg.ntpgs = ARRAY_SIZE(ipu6_tpg_offsets); isys_ipdata.tpg.offsets = ipu6_tpg_offsets; isys_ipdata.tpg.sels = NULL; -#endif isys_ipdata.num_parallel_streams = IPU6_ISYS_NUM_STREAMS; psys_ipdata.hw_variant.spc_offset = IPU6_PSYS_SPC_OFFSET; } else if (ipu_ver == IPU_VER_6SE) { isys_ipdata.csi2.nports = ARRAY_SIZE(ipu6se_csi_offsets); isys_ipdata.csi2.offsets = ipu6se_csi_offsets; -#ifdef CONFIG_VIDEO_INTEL_IPU_TPG isys_ipdata.tpg.ntpgs = ARRAY_SIZE(ipu6se_tpg_offsets); isys_ipdata.tpg.offsets = ipu6se_tpg_offsets; isys_ipdata.tpg.sels = NULL; -#endif isys_ipdata.num_parallel_streams = IPU6SE_ISYS_NUM_STREAMS; psys_ipdata.hw_variant.spc_offset = IPU6SE_PSYS_SPC_OFFSET; } diff --git a/drivers/media/pci/intel/ipu6/ipu6ep-fw-resources.c b/drivers/media/pci/intel/ipu6/ipu6ep-fw-resources.c new file mode 100644 index 000000000000..ca2ab3967e5c --- /dev/null +++ b/drivers/media/pci/intel/ipu6/ipu6ep-fw-resources.c @@ -0,0 +1,393 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2020 Intel Corporation + +#include +#include + +#include "ipu-psys.h" +#include "ipu-fw-psys.h" +#include "ipu6-platform-resources.h" +#include "ipu6ep-platform-resources.h" + +/* resources table */ + +/* + * Cell types by cell IDs + */ +const u8 ipu6ep_fw_psys_cell_types[IPU6EP_FW_PSYS_N_CELL_ID] = { + IPU6_FW_PSYS_SP_CTRL_TYPE_ID, + IPU6_FW_PSYS_VP_TYPE_ID, + IPU6_FW_PSYS_ACC_PSA_TYPE_ID, + IPU6_FW_PSYS_ACC_PSA_TYPE_ID, + IPU6_FW_PSYS_ACC_PSA_TYPE_ID, + IPU6_FW_PSYS_ACC_PSA_TYPE_ID, + IPU6_FW_PSYS_ACC_OSA_TYPE_ID, + IPU6_FW_PSYS_ACC_OSA_TYPE_ID, + IPU6_FW_PSYS_ACC_OSA_TYPE_ID, + IPU6_FW_PSYS_ACC_PSA_TYPE_ID, + IPU6_FW_PSYS_ACC_PSA_TYPE_ID, + IPU6_FW_PSYS_ACC_PSA_TYPE_ID, + IPU6_FW_PSYS_ACC_PSA_TYPE_ID, + IPU6_FW_PSYS_ACC_ISA_TYPE_ID, + IPU6_FW_PSYS_ACC_ISA_TYPE_ID, + IPU6_FW_PSYS_ACC_ISA_TYPE_ID, + IPU6_FW_PSYS_ACC_ISA_TYPE_ID, + IPU6_FW_PSYS_ACC_ISA_TYPE_ID, + IPU6_FW_PSYS_ACC_ISA_TYPE_ID, + IPU6_FW_PSYS_ACC_ISA_TYPE_ID, + IPU6_FW_PSYS_ACC_ISA_TYPE_ID, + IPU6_FW_PSYS_ACC_ISA_TYPE_ID, + IPU6_FW_PSYS_ACC_ISA_TYPE_ID, + IPU6_FW_PSYS_ACC_ISA_TYPE_ID, /* AF */ + IPU6_FW_PSYS_ACC_ISA_TYPE_ID, /* X2B_MD */ + IPU6_FW_PSYS_ACC_ISA_TYPE_ID, /* X2B_SVE_RGBIR */ + IPU6_FW_PSYS_ACC_ISA_TYPE_ID, /* PAF */ + IPU6_FW_PSYS_GDC_TYPE_ID, + IPU6_FW_PSYS_TNR_TYPE_ID, +}; + +const u16 ipu6ep_fw_num_dev_channels[IPU6_FW_PSYS_N_DEV_CHN_ID] = { + IPU6_FW_PSYS_DEV_CHN_DMA_EXT0_MAX_SIZE, + IPU6_FW_PSYS_DEV_CHN_DMA_EXT1_READ_MAX_SIZE, + IPU6_FW_PSYS_DEV_CHN_DMA_EXT1_WRITE_MAX_SIZE, + IPU6_FW_PSYS_DEV_CHN_DMA_INTERNAL_MAX_SIZE, + IPU6_FW_PSYS_DEV_CHN_DMA_ISA_MAX_SIZE, +}; + +const u16 ipu6ep_fw_psys_mem_size[IPU6_FW_PSYS_N_MEM_ID] = { + IPU6_FW_PSYS_VMEM0_MAX_SIZE, + IPU6_FW_PSYS_TRANSFER_VMEM0_MAX_SIZE, + IPU6_FW_PSYS_TRANSFER_VMEM1_MAX_SIZE, + IPU6_FW_PSYS_LB_VMEM_MAX_SIZE, + IPU6_FW_PSYS_BAMEM0_MAX_SIZE, + IPU6_FW_PSYS_DMEM0_MAX_SIZE, + IPU6_FW_PSYS_DMEM1_MAX_SIZE, + IPU6_FW_PSYS_DMEM2_MAX_SIZE, + IPU6_FW_PSYS_DMEM3_MAX_SIZE, + IPU6_FW_PSYS_PMEM0_MAX_SIZE +}; + +const u16 ipu6ep_fw_psys_dfms[IPU6_FW_PSYS_N_DEV_DFM_ID] = { + IPU6_FW_PSYS_DEV_DFM_BB_FULL_PORT_ID_MAX_SIZE, + IPU6_FW_PSYS_DEV_DFM_BB_EMPTY_PORT_ID_MAX_SIZE, + IPU6_FW_PSYS_DEV_DFM_ISL_FULL_PORT_ID_MAX_SIZE, + IPU6_FW_PSYS_DEV_DFM_ISL_EMPTY_PORT_ID_MAX_SIZE, + IPU6_FW_PSYS_DEV_DFM_LB_FULL_PORT_ID_MAX_SIZE, + IPU6_FW_PSYS_DEV_DFM_LB_EMPTY_PORT_ID_MAX_SIZE, +}; + +const u8 +ipu6ep_fw_psys_c_mem[IPU6EP_FW_PSYS_N_CELL_ID][IPU6_FW_PSYS_N_MEM_TYPE_ID] = { + { + /* IPU6_FW_PSYS_SP0_ID */ + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_DMEM0_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + }, + { + /* IPU6_FW_PSYS_SP1_ID */ + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_DMEM1_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + }, + { + /* IPU6_FW_PSYS_VP0_ID */ + IPU6_FW_PSYS_TRANSFER_VMEM0_ID, + IPU6_FW_PSYS_TRANSFER_VMEM1_ID, + IPU6_FW_PSYS_LB_VMEM_ID, + IPU6_FW_PSYS_DMEM3_ID, + IPU6_FW_PSYS_VMEM0_ID, + IPU6_FW_PSYS_BAMEM0_ID, + IPU6_FW_PSYS_PMEM0_ID, + }, + { + /* IPU6_FW_PSYS_ACC1_ID BNLM */ + IPU6_FW_PSYS_TRANSFER_VMEM0_ID, + IPU6_FW_PSYS_TRANSFER_VMEM1_ID, + IPU6_FW_PSYS_LB_VMEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + }, + { + /* IPU6_FW_PSYS_ACC2_ID DM */ + IPU6_FW_PSYS_TRANSFER_VMEM0_ID, + IPU6_FW_PSYS_TRANSFER_VMEM1_ID, + IPU6_FW_PSYS_LB_VMEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + }, + { + /* IPU6_FW_PSYS_ACC3_ID ACM */ + IPU6_FW_PSYS_TRANSFER_VMEM0_ID, + IPU6_FW_PSYS_TRANSFER_VMEM1_ID, + IPU6_FW_PSYS_LB_VMEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + }, + { + /* IPU6_FW_PSYS_ACC4_ID GTC YUV1 */ + IPU6_FW_PSYS_TRANSFER_VMEM0_ID, + IPU6_FW_PSYS_TRANSFER_VMEM1_ID, + IPU6_FW_PSYS_LB_VMEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + }, + { + /* IPU6_FW_PSYS_ACC5_ID OFS pin main */ + IPU6_FW_PSYS_TRANSFER_VMEM0_ID, + IPU6_FW_PSYS_TRANSFER_VMEM1_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + }, + { + /* IPU6_FW_PSYS_ACC6_ID OFS pin display */ + IPU6_FW_PSYS_TRANSFER_VMEM0_ID, + IPU6_FW_PSYS_TRANSFER_VMEM1_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + }, + { + /* IPU6_FW_PSYS_ACC7_ID OFS pin pp */ + IPU6_FW_PSYS_TRANSFER_VMEM0_ID, + IPU6_FW_PSYS_TRANSFER_VMEM1_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + }, + { + /* IPU6_FW_PSYS_ACC8_ID GAMMASTAR */ + IPU6_FW_PSYS_TRANSFER_VMEM0_ID, + IPU6_FW_PSYS_TRANSFER_VMEM1_ID, + IPU6_FW_PSYS_LB_VMEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + }, + { + /* IPU6_FW_PSYS_ACC9_ID GLTM */ + IPU6_FW_PSYS_TRANSFER_VMEM0_ID, + IPU6_FW_PSYS_TRANSFER_VMEM1_ID, + IPU6_FW_PSYS_LB_VMEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + }, + { + /* IPU6_FW_PSYS_ACC10_ID XNR */ + IPU6_FW_PSYS_TRANSFER_VMEM0_ID, + IPU6_FW_PSYS_TRANSFER_VMEM1_ID, + IPU6_FW_PSYS_LB_VMEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + }, + { + /* IPU6_FW_PSYS_ISA_ICA_ID */ + IPU6_FW_PSYS_TRANSFER_VMEM0_ID, + IPU6_FW_PSYS_TRANSFER_VMEM1_ID, + IPU6_FW_PSYS_LB_VMEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + }, + { + /* IPU6_FW_PSYS_ISA_LSC_ID */ + IPU6_FW_PSYS_TRANSFER_VMEM0_ID, + IPU6_FW_PSYS_TRANSFER_VMEM1_ID, + IPU6_FW_PSYS_LB_VMEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + }, + { + /* IPU6_FW_PSYS_ISA_DPC_ID */ + IPU6_FW_PSYS_TRANSFER_VMEM0_ID, + IPU6_FW_PSYS_TRANSFER_VMEM1_ID, + IPU6_FW_PSYS_LB_VMEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + }, + { + /* IPU6_FW_PSYS_ISA_SIS_A_ID */ + IPU6_FW_PSYS_TRANSFER_VMEM0_ID, + IPU6_FW_PSYS_TRANSFER_VMEM1_ID, + IPU6_FW_PSYS_LB_VMEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + }, + { + /* IPU6_FW_PSYS_ISA_SIS_B_ID */ + IPU6_FW_PSYS_TRANSFER_VMEM0_ID, + IPU6_FW_PSYS_TRANSFER_VMEM1_ID, + IPU6_FW_PSYS_LB_VMEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + }, + { + /* IPU6_FW_PSYS_ISA_B2B_ID */ + IPU6_FW_PSYS_TRANSFER_VMEM0_ID, + IPU6_FW_PSYS_TRANSFER_VMEM1_ID, + IPU6_FW_PSYS_LB_VMEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + }, + { + /* IPU6_FW_PSYS_ISA_B2R_ID and ISA_R2I_SIE */ + IPU6_FW_PSYS_TRANSFER_VMEM0_ID, + IPU6_FW_PSYS_TRANSFER_VMEM1_ID, + IPU6_FW_PSYS_LB_VMEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + }, + { + /* IPU6_FW_PSYS_ISA_R2I_DS_A_ID */ + IPU6_FW_PSYS_TRANSFER_VMEM0_ID, + IPU6_FW_PSYS_TRANSFER_VMEM1_ID, + IPU6_FW_PSYS_LB_VMEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + }, + { + /* IPU6_FW_PSYS_ISA_AWB_ID */ + IPU6_FW_PSYS_TRANSFER_VMEM0_ID, + IPU6_FW_PSYS_TRANSFER_VMEM1_ID, + IPU6_FW_PSYS_LB_VMEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + }, + { + /* IPU6_FW_PSYS_ISA_AE_ID */ + IPU6_FW_PSYS_TRANSFER_VMEM0_ID, + IPU6_FW_PSYS_TRANSFER_VMEM1_ID, + IPU6_FW_PSYS_LB_VMEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + }, + { + /* IPU6_FW_PSYS_ISA_AF_ID */ + IPU6_FW_PSYS_TRANSFER_VMEM0_ID, + IPU6_FW_PSYS_TRANSFER_VMEM1_ID, + IPU6_FW_PSYS_LB_VMEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + }, + { + /* IPU6_FW_PSYS_ISA_X2B_MD_ID */ + IPU6_FW_PSYS_TRANSFER_VMEM0_ID, + IPU6_FW_PSYS_TRANSFER_VMEM1_ID, + IPU6_FW_PSYS_LB_VMEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + }, + { + /* IPU6_FW_PSYS_ISA_X2B_SVE_RGBIR_ID */ + IPU6_FW_PSYS_TRANSFER_VMEM0_ID, + IPU6_FW_PSYS_TRANSFER_VMEM1_ID, + IPU6_FW_PSYS_LB_VMEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + }, + { + /* IPU6_FW_PSYS_ISA_PAF_ID */ + IPU6_FW_PSYS_TRANSFER_VMEM0_ID, + IPU6_FW_PSYS_TRANSFER_VMEM1_ID, + IPU6_FW_PSYS_LB_VMEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + }, + { + /* IPU6_FW_PSYS_BB_ACC_GDC0_ID */ + IPU6_FW_PSYS_TRANSFER_VMEM0_ID, + IPU6_FW_PSYS_TRANSFER_VMEM1_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + }, + { + /* IPU6_FW_PSYS_BB_ACC_TNR_ID */ + IPU6_FW_PSYS_TRANSFER_VMEM0_ID, + IPU6_FW_PSYS_TRANSFER_VMEM1_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + IPU6_FW_PSYS_N_MEM_ID, + } +}; + +static const struct ipu_fw_resource_definitions ipu6ep_defs = { + .cells = ipu6ep_fw_psys_cell_types, + .num_cells = IPU6EP_FW_PSYS_N_CELL_ID, + .num_cells_type = IPU6_FW_PSYS_N_CELL_TYPE_ID, + + .dev_channels = ipu6ep_fw_num_dev_channels, + .num_dev_channels = IPU6_FW_PSYS_N_DEV_CHN_ID, + + .num_ext_mem_types = IPU6_FW_PSYS_N_DATA_MEM_TYPE_ID, + .num_ext_mem_ids = IPU6_FW_PSYS_N_MEM_ID, + .ext_mem_ids = ipu6ep_fw_psys_mem_size, + + .num_dfm_ids = IPU6_FW_PSYS_N_DEV_DFM_ID, + + .dfms = ipu6ep_fw_psys_dfms, + + .cell_mem_row = IPU6_FW_PSYS_N_MEM_TYPE_ID, + .cell_mem = &ipu6ep_fw_psys_c_mem[0][0], +}; + +const struct ipu_fw_resource_definitions *ipu6ep_res_defs = &ipu6ep_defs; diff --git a/drivers/media/pci/intel/ipu6/ipu6ep-platform-resources.h b/drivers/media/pci/intel/ipu6/ipu6ep-platform-resources.h new file mode 100644 index 000000000000..7776ea986940 --- /dev/null +++ b/drivers/media/pci/intel/ipu6/ipu6ep-platform-resources.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2020 Intel Corporation */ + +#ifndef IPU6EP_PLATFORM_RESOURCES_H +#define IPU6EP_PLATFORM_RESOURCES_H + +#include +#include + +enum { + IPU6EP_FW_PSYS_SP0_ID = 0, + IPU6EP_FW_PSYS_VP0_ID, + IPU6EP_FW_PSYS_PSA_ACC_BNLM_ID, + IPU6EP_FW_PSYS_PSA_ACC_DM_ID, + IPU6EP_FW_PSYS_PSA_ACC_ACM_ID, + IPU6EP_FW_PSYS_PSA_ACC_GTC_YUV1_ID, + IPU6EP_FW_PSYS_BB_ACC_OFS_PIN_MAIN_ID, + IPU6EP_FW_PSYS_BB_ACC_OFS_PIN_DISPLAY_ID, + IPU6EP_FW_PSYS_BB_ACC_OFS_PIN_PP_ID, + IPU6EP_FW_PSYS_PSA_ACC_GAMMASTAR_ID, + IPU6EP_FW_PSYS_PSA_ACC_GLTM_ID, + IPU6EP_FW_PSYS_PSA_ACC_XNR_ID, + IPU6EP_FW_PSYS_PSA_VCSC_ID, /* VCSC */ + IPU6EP_FW_PSYS_ISA_ICA_ID, + IPU6EP_FW_PSYS_ISA_LSC_ID, + IPU6EP_FW_PSYS_ISA_DPC_ID, + IPU6EP_FW_PSYS_ISA_SIS_A_ID, + IPU6EP_FW_PSYS_ISA_SIS_B_ID, + IPU6EP_FW_PSYS_ISA_B2B_ID, + IPU6EP_FW_PSYS_ISA_B2R_R2I_SIE_ID, + IPU6EP_FW_PSYS_ISA_R2I_DS_A_ID, + IPU6EP_FW_PSYS_ISA_AWB_ID, + IPU6EP_FW_PSYS_ISA_AE_ID, + IPU6EP_FW_PSYS_ISA_AF_ID, + IPU6EP_FW_PSYS_ISA_X2B_MD_ID, + IPU6EP_FW_PSYS_ISA_X2B_SVE_RGBIR_ID, + IPU6EP_FW_PSYS_ISA_PAF_ID, + IPU6EP_FW_PSYS_BB_ACC_GDC0_ID, + IPU6EP_FW_PSYS_BB_ACC_TNR_ID, + IPU6EP_FW_PSYS_N_CELL_ID +}; +#endif /* IPU6EP_PLATFORM_RESOURCES_H */